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

6 投票
5 回答
16431 浏览
提问于 2025-04-15 20:59

我想比较两个长度不一样的嵌套列表。我只关心每个子列表的第一个元素之间是否匹配。如果有匹配的情况,我想把这个匹配的结果放到另一个列表中,以便后续转换成一个用制表符分隔的文件。下面是我正在处理的一个例子:

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']]

重新处理这个列表以去除重复项是否是个好习惯,还是说有更简单的方法可以做到这一点?

另外,出于比较的目的,使用元组或者元组的元组更好么?

非常感谢你的帮助。

祝好,
Seafoid。

5 个回答

2

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

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

我不确定我是否理解了你的问题,不过根据你的例子来看,似乎你可能用了错误的索引:

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

改成

if i[0] == j[0]:
6
  • 使用集合来获得没有重复项的集合。

    • 你需要用元组来代替列表,因为集合里的元素必须是可哈希的,也就是说它们必须是不可变的。
  • 你发的代码似乎没有生成你展示的输出。我不明白你是怎么从那个输入生成那个输出的。比如,输出中有 'y',但输入中没有。

  • 我觉得你的函数设计可以大大改进。目前你把 xymatch 定义在模块级别,并且直接读取和修改它们。这不是函数设计的好方法——一般来说,函数不应该修改全局变量。它应该明确地接收所有需要的参数,并返回结果,而不是隐式地接收信息并改变外部的东西。

    我会把

    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()
    

    改成

    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)
    
  • 为了进一步改进最后的变化,我通常会把模式

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

    替换成类似的生成器

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

    这样可以让上面的函数变成

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

    用生成器表达式 (j for i in x for j in y if i[0] == j[0]) 来表达这个生成器的效果。

撰写回答