【问题标题】:How can I compare two lists in python and return not matches如何比较python中的两个列表并返回不匹配
【发布时间】:2016-03-01 01:29:57
【问题描述】:

我想从两个列表中返回不在另一个列表中的值:

bar = [ 1,2,3,4,5 ]
foo = [ 1,2,3,6 ]

returnNotMatches( a,b )

会返回

[[ 4,5 ],[ 6 ]]

【问题讨论】:

  • 太棒了。到目前为止你尝试了什么
  • bar = [1,2,3,4,5,6]; foo = [1,2,3,5,6] 的结果应该是什么?
  • 您是否习惯于使用列表? set 可能吗?

标签: python


【解决方案1】:

其中一个最简单、最快捷的是:

new_list = list(set(list1).difference(list2))

奖金! 如果你想要一个交叉点(返回匹配项):

new_list = list(set(list1).intersection(list2))

【讨论】:

  • 嘿@user3885769 我相信你的两行代码是相同的
  • 这比根据所选答案遍历两个列表要快得多。比较两个具有约 200,000 个 uuid 的列表对我来说从 5 分钟以上到亚秒级。
  • 如果使用list()构造函数,则不需要使用[]。
【解决方案2】:

只需使用列表推导:

def returnNotMatches(a, b):
    return [[x for x in a if x not in b], [x for x in b if x not in a]]

【讨论】:

    【解决方案3】:

    应该这样做

    def returnNotMatches(a, b):
        a = set(a)
        b = set(b)
        return [list(b - a), list(a - b)]
    

    如果你不关心结果应该是一个列表,你可以跳过最后的演员表。

    【讨论】:

    • 这将丢弃 a 或 b 中不匹配的重复项。
    • 会的,但是将匹配项与重复项进行比较毫无意义。
    • 除非它有意义......我认为你不能在不了解应用程序的情况下断言它没有目的。
    • “我想从两个列表中返回不在另一个列表中的值”显然意味着将列表视为一个集合。
    • 按照字面意思,[4, 5, 6] 将是所需的输出。我在关于集合的问题中添加了评论,因为他们可能一开始就应该使用集合作为他们的数据结构。
    【解决方案4】:

    我可能会依赖这里的标准库...

    from itertools import tee, izip
    def pairwise(iterable):
        "s -> (s0,s1), (s1,s2), (s2, s3), ..."
        a, b = tee(iterable)
        next(b, None)
        return izip(a, b)
    
    import difflib
    
    def returnNotMatches(a, b):
        blocks = difflib.SequenceMatcher(a=a, b=b).get_matching_blocks()
        differences = []
        for b1, b2 in pairwise(blocks):
            d1 = a[b1.a + b1.size: b2.a]
            d2 = b[b1.b + b1.size: b2.b]
            differences.append((d1, d2))
        return differences
    
    print returnNotMatches([ 1,2,3,4,5 ], [ 1,2,3,6 ])
    

    打印:[([4, 5], [6])]

    这会将序列作为流进行比较,并找出流中的差异。它考虑了顺序等。如果顺序和重复不很重要,那么sets 是目前为止的最佳选择(只要元素可以被散列)。

    【讨论】:

    • o.o 虽然difflib 是一个很酷的库,但这是一个机器人帖子吗?乍一看,这段代码看起来很真实,pairwise 是一个有趣的函数,但它没有被使用,differences 没有被使用,并且代码抛出了一个ValueError...
    • @JaredGoguen -- 我不同意......当序列长度不同并且不匹配值的不同块的长度不同时,在序列中找到匹配块是非常重要的(尤其是考虑到答案甚至不一定是唯一的)。因此存在difflib :-)
    • @JaredGoguen --谢谢,显然是一起破解代码而不是保持更新......
    • NameError: name 'size' is not defined 仍然
    • 我个人对那个代码很好奇(这就是为什么连续的 cmets),而不是试图吹毛求疵。我认为您可能回答了错误的问题,zondo 的答案是 Pythonic 且正确的(尽管可能效率低下,但不应该经常为了 Python 的效率而牺牲可读性)。
    【解决方案5】:

    你可以使用列表推导和压缩

    ''.join([i[0] for i in zip(a, a.lower()) if i[0] == i[1]])
    

    【讨论】:

      猜你喜欢
      • 2010-11-26
      • 1970-01-01
      • 2020-12-19
      • 1970-01-01
      • 2012-05-09
      • 2016-12-23
      • 1970-01-01
      • 2023-03-04
      • 1970-01-01
      相关资源
      最近更新 更多