Python - 比较嵌套列表并将匹配项附加到新列表?

发布于 2024-08-27 03:49:45 字数 576 浏览 5 评论 0原文

我希望与不等长度的嵌套列表进行比较。我只对每个子列表的第一个元素之间的匹配感兴趣。如果存在匹配项,我希望将匹配项添加到另一个列表中,以便随后转换为制表符分隔文件。这是我正在处理的示例:

x = [['1', 'a', 'b'], ['2', 'c', 'd']]

y = [['1', 'z', 'x'], ['4', 'z', 'x']]

match = []

def find_match():
    for i in x:
        for j in y:
            if i[0] == j[0]:
                 match.append(j)
            return match

这返回:

[['1', 'x'], ['1', 'y'], ['1', 'x'], ['1', 'y'], ['1', 'z', 'x']]

重新处理列表以删除重复项是一个好的做法还是可以以更简单的方式完成?

另外,出于比较的目的,使用元组和/或元组的元组是否更好?

非常感谢任何帮助。

问候, 海鲜。

I wish to compare to nested lists of unequal length. I am interested only in a match between the first element of each sub list. Should a match exist, I wish to add the match to another list for subsequent transformation into a tab delimited file. Here is an example of what I am working with:

x = [['1', 'a', 'b'], ['2', 'c', 'd']]

y = [['1', 'z', 'x'], ['4', 'z', 'x']]

match = []

def find_match():
    for i in x:
        for j in y:
            if i[0] == j[0]:
                 match.append(j)
            return match

This returns:

[['1', 'x'], ['1', 'y'], ['1', 'x'], ['1', 'y'], ['1', 'z', 'x']]

Would it be good practise to reprocess the list to remove duplicates or can this be done in a simpler fashion?

Also, is it better to use tuples and/or tuples of tuples for the purposes of comparison?

Any help is greatly appreciated.

Regards,
Seafoid.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

孤独患者 2024-09-03 03:49:45
  • 使用集合来获取没有重复项的集合。

    • 您必须使用元组而不是列表作为项目,因为集合项目必须是可散列的。
  • 您发布的代码似乎没有生成您发布的输出。我不知道你应该如何从该输入生成该输出。例如,输出具有 'y' 而输入则没有。

  • 我认为你的功能设计还有待改进。目前,您将 xymatch 定义为模块级别,并显式读取和更改它们。这不是你想要的函数设计方式——一般来说,函数不应该在全局层面上改变某些东西。它应该显式地传递它需要的所有内容并返回结果,而不是隐式地接收信息并更改其自身之外的某些内容。

    我会改变

    x = 一些列表
    y = 一些列表
    匹配=[]
    def find_match():
        对于 x 中的 i:
            对于 y 中的 j:
                如果 i[0] == j[0]:
                     匹配.追加(j)
        return match # 这是我更改的唯一一行。我想你的意思是 
                     # 你会回到这里吗?
    查找匹配()
    

    x = 一些列表
    y = 一些列表
    
    def find_match(x, y):
        匹配 = []
        对于 x 中的 i:
            对于 y 中的 j:
                如果 i[0] == j[0]:
                     匹配.追加(j)
         返回匹配项
    匹配 = find_match(x, y)
    
  • 为了将最后的更改提升到下一个级别,我通常会替换模式

    <前><代码>def f(...):
    返回值 = []
    为了...
    return_value.append(foo)
    返回return_value

    使用类似的生成器

    <前><代码>def f(...):
    为了...
    产量富

    这将实现上述功能

    def find_match(x, y):
        对于 x 中的 i:
            对于 y 中的 j:
                如果 i[0] == j[0]:
                     产量 j
    

    表达此生成器效果的另一种方法是使用生成器表达式(j for i in x for j in y if i[0] == j[0])

  • Use sets to obtain collections with no duplicates.

    • You'll have to use tuples instead of lists as the items because set items must be hashable.
  • The code you posted doesn't seem to generate the output you posted. I do not have any idea how you are supposed to generate that output from that input. For example, the output has 'y' and the input does not.

  • I think the design of your function could be much improved. Currently you define x, y, and match as the module level and read and mutate them explicitly. This is not how you want to design functions—as a general rule, a function shouldn't mutate something at the global level. It should be explicitly passed everything it needs and return a result, not implicitly receive information and change something outside itself.

    I would change

    x = some list
    y = some list
    match = []
    def find_match():
        for i in x:
            for j in y:
                if i[0] == j[0]:
                     match.append(j)
        return match # This is the only line I changed. I think you meant 
                     # your return to be over here?
    find_match()
    

    to

    x = some list
    y = some list
    
    def find_match(x, y):
        match = []
        for i in x:
            for j in y:
                if i[0] == j[0]:
                     match.append(j)
         return match
    match = find_match(x, y)
    
  • To take that last change to the next level, I usually replace the pattern

    def f(...):
        return_value = []
        for...
            return_value.append(foo)
        return return_value
    

    with the similar generator

    def f(...):
        for...
            yield foo
    

    which would make the above function

    def find_match(x, y):
        for i in x:
            for j in y:
                if i[0] == j[0]:
                     yield j
    

    another way to express this generator's effect is with the generator expression (j for i in x for j in y if i[0] == j[0]).

若相惜即相离 2024-09-03 03:49:45

我不知道我是否正确解释了您的问题,但鉴于您的示例,您似乎可能使用了错误的索引:

更改

if i[1] == j[1]:

if i[0] == j[0]:

I don't know if I interpret your question correctly, but given your example it seems that you might be using a wrong index:

change

if i[1] == j[1]:

into

if i[0] == j[0]:
往日 2024-09-03 03:49:45

通过使用集合,您可以更简单地做到这一点。

set_x = set([i[0] for i in x])
set_y = set([i[0] for i in y])
matches = list(set_x & set_y)

You can do this a lot more simply by using sets.

set_x = set([i[0] for i in x])
set_y = set([i[0] for i in y])
matches = list(set_x & set_y)
剩余の解释 2024-09-03 03:49:45
if i[1] == j[1]

检查数组的第二个元素是否相同。您需要if i[0] == j[0]

否则,我发现您的代码非常可读,并且不一定会更改它。

if i[1] == j[1]

checks whether the second elements of the arrays are identical. You want if i[0] == j[0].

Otherwise, I find your code quite readable and wouldn't necessarily change it.

半寸时光 2024-09-03 03:49:45

更简单的表达式也应该在这里工作:

list_of_lists = filter(lambda l: l[0][0] == l[1][0], zip(x, y))
map(lambda l: l[1], list_of_lists)

A simplier expression should work here too:

list_of_lists = filter(lambda l: l[0][0] == l[1][0], zip(x, y))
map(lambda l: l[1], list_of_lists)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文