【问题标题】:Get difference between two lists获取两个列表之间的差异
【发布时间】:2011-03-28 14:08:57
【问题描述】:

我在 Python 中有两个列表,如下所示:

temp1 = ['One', 'Two', 'Three', 'Four']
temp2 = ['One', 'Two']

我需要创建第三个列表,其中包含第一个列表中不存在于第二个列表中的项目。从我必须得到的例子中

temp3 = ['Three', 'Four']

有没有没有循环和检查的快速方法?

【问题讨论】:

  • 元素是否保证唯一?如果你有temp1 = ['One', 'One', 'One']temp2 = ['One'],你想要['One', 'One'],还是[]
  • @michael-mrozek 他们是独一无二的。
  • 是否要保留元素的顺序?
  • 这能回答你的问题吗? Finding elements not in a list

标签: python performance list set set-difference


【解决方案1】:

获取temp1 中但不在temp2 中的元素:

In [5]: list(set(temp1) - set(temp2))
Out[5]: ['Four', 'Three']

注意它是不对称的:

In [5]: set([1, 2]) - set([2, 3])
Out[5]: set([1]) 

您可能期望/希望它等于set([1, 3])。如果您确实想要set([1, 3]) 作为您的答案,您可以使用set([1, 2]).symmetric_difference(set([2, 3]))

【讨论】:

  • @Drewdin:列表不支持“-”操作数。然而,集合确实如此,如果你仔细观察的话,上面已经证明了这一点。
  • 对称差可以写成:^ (set1 ^ set2)
  • 请注意,由于集合是无序的,因此差异的迭代器可以以任何顺序返回元素。例如,list(set(temp1) - set(temp2)) == ['Four', 'Three'] list(set(temp1) - set(temp2)) == ['Three', 'Four'].
  • 此方法不保留输入列表的顺序。
  • 如果有重复元素怎么办?例如a=[1, 1, 1, 1, 2, 2], b=[1, 1, 2, 2]
【解决方案2】:

现有的解决方案都提供以下一种或另一种:

  • 比 O(n*m) 性能更快。
  • 保留输入列表的顺序。

但到目前为止,还没有解决方案兼具两者。如果你想要两者,试试这个:

s = set(temp2)
temp3 = [x for x in temp1 if x not in s]

性能测试

import timeit
init = 'temp1 = list(range(100)); temp2 = [i * 2 for i in range(50)]'
print timeit.timeit('list(set(temp1) - set(temp2))', init, number = 100000)
print timeit.timeit('s = set(temp2);[x for x in temp1 if x not in s]', init, number = 100000)
print timeit.timeit('[item for item in temp1 if item not in temp2]', init, number = 100000)

结果:

4.34620224079 # ars' answer
4.2770634955  # This answer
30.7715615392 # matt b's answer

我提出的方法以及保留顺序也(略)比集合减法快,因为它不需要构造不必要的集合。如果第一个列表比第二个列表长得多并且散列很昂贵,则性能差异会更加明显。这是证明这一点的第二个测试:

init = '''
temp1 = [str(i) for i in range(100000)]
temp2 = [str(i * 2) for i in range(50)]
'''

结果:

11.3836875916 # ars' answer
3.63890368748 # this answer (3 times faster!)
37.7445402279 # matt b's answer

【讨论】:

  • 对此答案的额外支持:遇到一个用例,其中保留列表顺序对性能很重要。使用 tarinfo 或 zipinfo 对象时,我使用的是集合减法。从存档中提取某些 tarinfo 对象。创建新列表很快,但在提取过程中非常慢。原因一开始我就回避了。事实证明,重新排序 tarinfo 对象列表会导致巨大的性能损失。切换到列表理解方法节省了一天的时间。
  • @MarkByers - 也许我应该为此写一个全新的问题。但是这将如何在 forloop 中工作?例如,如果我的 temp1 和 temp2 不断变化......并且我想将新信息附加到 temp3?
  • @MarkByers - 听起来不错。我会继续考虑一下。但是 +1 是一个很好的解决方案。
  • 我同意@Dejel >>> temp1 = ['One', 'Two', 'Three', 'Four'] >>> temp2 = ['One', 'Two', '六'] >>> s = set(temp2) >>> temp3 = [x for x in temp1 if x not in s] >>> temp3 ['Three', 'Four']
  • @hacks 因为检查列表的成员资格是 O(n) 操作(遍历整个列表),但检查集合的成员资格是 O(1)。
【解决方案3】:

可以使用 python XOR 运算符来完成。

  • 这将删除每个列表中的重复项
  • 这将显示 temp1 与 temp2 以及 temp2 与 temp1 的差异。

set(temp1) ^ set(temp2)

【讨论】:

  • 最佳答案!
  • 这个是怎么埋起来的……很棒的电话
  • 该死的。这是一个更好的解决方案!
  • 好发现!我总是忽略文档的这一部分:docs.python.org/3/library/….
  • @Gangula 要查看这两种方法之间的区别,请向temp2 添加一个在temp1 中不存在的值,然后重试。
【解决方案4】:
temp3 = [item for item in temp1 if item not in temp2]

【讨论】:

  • temp2 转换为之前的集合会提高效率。
  • 是的,取决于 Ockonal 是否关心重复(原始问题没有说)
  • 评论说(列表|元组)没有重复。
  • 我赞成您的回答,因为我一开始认为您对重复项是正确的。但是item not in temp2item not in set(temp2) 将始终返回相同的结果,无论temp2 中是否存在重复。
  • 赞成不要求列表项可散列。
【解决方案5】:

两个列表(比如 list1 和 list2)之间的区别可以使用以下简单函数找到。

def diff(list1, list2):
    c = set(list1).union(set(list2))  # or c = set(list1) | set(list2)
    d = set(list1).intersection(set(list2))  # or d = set(list1) & set(list2)
    return list(c - d)

def diff(list1, list2):
    return list(set(list1).symmetric_difference(set(list2)))  # or return list(set(list1) ^ set(list2))

通过使用上述函数,可以使用diff(temp2, temp1)diff(temp1, temp2) 找到差异。两者都会给出结果['Four', 'Three']。您不必担心列表的顺序或首先给出哪个列表。

Python doc reference

【讨论】:

  • 为什么不 set(list1).symmetric_difference(set(list2))?
【解决方案6】:

如果您想要递归地进行差异化,我已经为 python 编写了一个包: https://github.com/seperman/deepdiff

安装

从 PyPi 安装:

pip install deepdiff

示例用法

导入

>>> from deepdiff import DeepDiff
>>> from pprint import pprint
>>> from __future__ import print_function # In case running on Python 2

相同的对象返回空

>>> t1 = {1:1, 2:2, 3:3}
>>> t2 = t1
>>> print(DeepDiff(t1, t2))
{}

项目类型已更改

>>> t1 = {1:1, 2:2, 3:3}
>>> t2 = {1:1, 2:"2", 3:3}
>>> pprint(DeepDiff(t1, t2), indent=2)
{ 'type_changes': { 'root[2]': { 'newtype': <class 'str'>,
                                 'newvalue': '2',
                                 'oldtype': <class 'int'>,
                                 'oldvalue': 2}}}

物品的价值发生了变化

>>> t1 = {1:1, 2:2, 3:3}
>>> t2 = {1:1, 2:4, 3:3}
>>> pprint(DeepDiff(t1, t2), indent=2)
{'values_changed': {'root[2]': {'newvalue': 4, 'oldvalue': 2}}}

添加和/或删除项目

>>> t1 = {1:1, 2:2, 3:3, 4:4}
>>> t2 = {1:1, 2:4, 3:3, 5:5, 6:6}
>>> ddiff = DeepDiff(t1, t2)
>>> pprint (ddiff)
{'dic_item_added': ['root[5]', 'root[6]'],
 'dic_item_removed': ['root[4]'],
 'values_changed': {'root[2]': {'newvalue': 4, 'oldvalue': 2}}}

字符串区别

>>> t1 = {1:1, 2:2, 3:3, 4:{"a":"hello", "b":"world"}}
>>> t2 = {1:1, 2:4, 3:3, 4:{"a":"hello", "b":"world!"}}
>>> ddiff = DeepDiff(t1, t2)
>>> pprint (ddiff, indent = 2)
{ 'values_changed': { 'root[2]': {'newvalue': 4, 'oldvalue': 2},
                      "root[4]['b']": { 'newvalue': 'world!',
                                        'oldvalue': 'world'}}}

字符串差异2

>>> t1 = {1:1, 2:2, 3:3, 4:{"a":"hello", "b":"world!\nGoodbye!\n1\n2\nEnd"}}
>>> t2 = {1:1, 2:2, 3:3, 4:{"a":"hello", "b":"world\n1\n2\nEnd"}}
>>> ddiff = DeepDiff(t1, t2)
>>> pprint (ddiff, indent = 2)
{ 'values_changed': { "root[4]['b']": { 'diff': '--- \n'
                                                '+++ \n'
                                                '@@ -1,5 +1,4 @@\n'
                                                '-world!\n'
                                                '-Goodbye!\n'
                                                '+world\n'
                                                ' 1\n'
                                                ' 2\n'
                                                ' End',
                                        'newvalue': 'world\n1\n2\nEnd',
                                        'oldvalue': 'world!\n'
                                                    'Goodbye!\n'
                                                    '1\n'
                                                    '2\n'
                                                    'End'}}}

>>> 
>>> print (ddiff['values_changed']["root[4]['b']"]["diff"])
--- 
+++ 
@@ -1,5 +1,4 @@
-world!
-Goodbye!
+world
 1
 2
 End

类型改变

>>> t1 = {1:1, 2:2, 3:3, 4:{"a":"hello", "b":[1, 2, 3]}}
>>> t2 = {1:1, 2:2, 3:3, 4:{"a":"hello", "b":"world\n\n\nEnd"}}
>>> ddiff = DeepDiff(t1, t2)
>>> pprint (ddiff, indent = 2)
{ 'type_changes': { "root[4]['b']": { 'newtype': <class 'str'>,
                                      'newvalue': 'world\n\n\nEnd',
                                      'oldtype': <class 'list'>,
                                      'oldvalue': [1, 2, 3]}}}

列表差异

>>> t1 = {1:1, 2:2, 3:3, 4:{"a":"hello", "b":[1, 2, 3, 4]}}
>>> t2 = {1:1, 2:2, 3:3, 4:{"a":"hello", "b":[1, 2]}}
>>> ddiff = DeepDiff(t1, t2)
>>> pprint (ddiff, indent = 2)
{'iterable_item_removed': {"root[4]['b'][2]": 3, "root[4]['b'][3]": 4}}

列出差异2:

>>> t1 = {1:1, 2:2, 3:3, 4:{"a":"hello", "b":[1, 2, 3]}}
>>> t2 = {1:1, 2:2, 3:3, 4:{"a":"hello", "b":[1, 3, 2, 3]}}
>>> ddiff = DeepDiff(t1, t2)
>>> pprint (ddiff, indent = 2)
{ 'iterable_item_added': {"root[4]['b'][3]": 3},
  'values_changed': { "root[4]['b'][1]": {'newvalue': 3, 'oldvalue': 2},
                      "root[4]['b'][2]": {'newvalue': 2, 'oldvalue': 3}}}

忽略顺序或重复列出差异:(使用与上述相同的字典)

>>> t1 = {1:1, 2:2, 3:3, 4:{"a":"hello", "b":[1, 2, 3]}}
>>> t2 = {1:1, 2:2, 3:3, 4:{"a":"hello", "b":[1, 3, 2, 3]}}
>>> ddiff = DeepDiff(t1, t2, ignore_order=True)
>>> print (ddiff)
{}

包含字典的列表:

>>> t1 = {1:1, 2:2, 3:3, 4:{"a":"hello", "b":[1, 2, {1:1, 2:2}]}}
>>> t2 = {1:1, 2:2, 3:3, 4:{"a":"hello", "b":[1, 2, {1:3}]}}
>>> ddiff = DeepDiff(t1, t2)
>>> pprint (ddiff, indent = 2)
{ 'dic_item_removed': ["root[4]['b'][2][2]"],
  'values_changed': {"root[4]['b'][2][1]": {'newvalue': 3, 'oldvalue': 1}}}

套装:

>>> t1 = {1, 2, 8}
>>> t2 = {1, 2, 3, 5}
>>> ddiff = DeepDiff(t1, t2)
>>> pprint (DeepDiff(t1, t2))
{'set_item_added': ['root[3]', 'root[5]'], 'set_item_removed': ['root[8]']}

命名元组:

>>> from collections import namedtuple
>>> Point = namedtuple('Point', ['x', 'y'])
>>> t1 = Point(x=11, y=22)
>>> t2 = Point(x=11, y=23)
>>> pprint (DeepDiff(t1, t2))
{'values_changed': {'root.y': {'newvalue': 23, 'oldvalue': 22}}}

自定义对象:

>>> class ClassA(object):
...     a = 1
...     def __init__(self, b):
...         self.b = b
... 
>>> t1 = ClassA(1)
>>> t2 = ClassA(2)
>>> 
>>> pprint(DeepDiff(t1, t2))
{'values_changed': {'root.b': {'newvalue': 2, 'oldvalue': 1}}}

添加了对象属性:

>>> t2.c = "new attribute"
>>> pprint(DeepDiff(t1, t2))
{'attribute_added': ['root.c'],
 'values_changed': {'root.b': {'newvalue': 2, 'oldvalue': 1}}}

【讨论】:

    【解决方案7】:

    最简单的方法,

    使用 set().difference(set())

    list_a = [1,2,3]
    list_b = [2,3]
    print set(list_a).difference(set(list_b))
    

    答案是set([1])

    可以打印成列表,

    print list(set(list_a).difference(set(list_b)))
    

    【讨论】:

    • 删除重复项并且不保留顺序
    【解决方案8】:

    试试这个:

    temp3 = set(temp1) - set(temp2)
    

    【讨论】:

      【解决方案9】:

      如果你真的在看性能,那就使用 numpy!

      这是 github 上的完整笔记本,其中包含 list、numpy 和 pandas 之间的比较。

      https://gist.github.com/denfromufa/2821ff59b02e9482be15d27f2bbd4451

      【讨论】:

      • 我更新了链接中的笔记本和屏幕截图。令人惊讶的是,即使在内部切换到哈希表时,pandas 也比 numpy 慢。部分原因可能是向上转换为 int64。
      • Mark Byers Answer 运行测试,numpy 获得了所有答案中最长的答案(ars、SuperNova、Mark Byers、Matt b)。
      【解决方案10】:

      我会折腾,因为目前的解决方案都没有产生元组:

      temp3 = tuple(set(temp1) - set(temp2))
      

      或者:

      #edited using @Mark Byers idea. If you accept this one as answer, just accept his instead.
      temp3 = tuple(x for x in temp1 if x not in set(temp2))
      

      像其他非元组在这个方向上产生答案一样,它保持顺序

      【讨论】:

        【解决方案11】:

        我想要一个可以包含两个列表并且可以做diff in bash 所做的事情。由于这个问题是在你搜索“python diff two lists”时首先弹出的,而且不是很具体,所以我会发布我想出的内容。

        使用来自difflibSequenceMather,您可以像diff 那样比较两个列表。其他答案都不会告诉您差异发生的位置,但这个答案可以。一些答案仅在一个方向上给出了差异。一些重新排序元素。有些不处理重复项。但是这个解决方案让你在两个列表之间有一个真正的区别:

        a = 'A quick fox jumps the lazy dog'.split()
        b = 'A quick brown mouse jumps over the dog'.split()
        
        from difflib import SequenceMatcher
        
        for tag, i, j, k, l in SequenceMatcher(None, a, b).get_opcodes():
          if tag == 'equal': print('both have', a[i:j])
          if tag in ('delete', 'replace'): print('  1st has', a[i:j])
          if tag in ('insert', 'replace'): print('  2nd has', b[k:l])
        

        这个输出:

        both have ['A', 'quick']
          1st has ['fox']
          2nd has ['brown', 'mouse']
        both have ['jumps']
          2nd has ['over']
        both have ['the']
          1st has ['lazy']
        both have ['dog']
        

        当然,如果您的应用程序做出与其他答案相同的假设,您将从中受益最多。但是,如果您正在寻找真正的 diff 功能,那么这是唯一的出路。

        例如,没有其他答案可以处理:

        a = [1,2,3,4,5]
        b = [5,4,3,2,1]
        

        但是这个可以:

          2nd has [5, 4, 3, 2]
        both have [1]
          1st has [2, 3, 4, 5]
        

        【讨论】:

          【解决方案12】:

          这是最简单情况的Counter 答案。

          这比上面的双向差异要短,因为它只执行问题所要求的内容:生成第一个列表中的内容而不是第二个列表中的内容。

          from collections import Counter
          
          lst1 = ['One', 'Two', 'Three', 'Four']
          lst2 = ['One', 'Two']
          
          c1 = Counter(lst1)
          c2 = Counter(lst2)
          diff = list((c1 - c2).elements())
          

          或者,根据您的可读性偏好,它是一个不错的单行:

          diff = list((Counter(lst1) - Counter(lst2)).elements())
          

          输出:

          ['Three', 'Four']
          

          请注意,如果您只是对其进行迭代,则可以删除 list(...) 调用。

          由于此解决方案使用计数器,因此与许多基于集合的答案相比,它可以正确处理数量。例如在这个输入上:

          lst1 = ['One', 'Two', 'Two', 'Two', 'Three', 'Three', 'Four']
          lst2 = ['One', 'Two']
          

          输出是:

          ['Two', 'Two', 'Three', 'Three', 'Four']
          

          【讨论】:

          • 干得好!这是正确的、普遍的答案。
          【解决方案13】:

          这可能比 Mark 的列表理解还要快:

          list(itertools.filterfalse(set(temp2).__contains__, temp1))
          

          【讨论】:

          • 可能希望在此处包含 from itertools import filterfalse 位。另请注意,这不会像其他人一样返回序列,而是返回一个迭代器。
          【解决方案14】:

          这里有一些简单的顺序保留方法来区分两个字符串列表。

          代码

          使用pathlib 的不寻常方法:

          import pathlib
          
          
          temp1 = ["One", "Two", "Three", "Four"]
          temp2 = ["One", "Two"]
          
          p = pathlib.Path(*temp1)
          r = p.relative_to(*temp2)
          list(r.parts)
          # ['Three', 'Four']
          

          这假定两个列表都包含具有相同开头的字符串。有关详细信息,请参阅docs。请注意,与集合操作相比,它并不是特别快。


          使用itertools.zip_longest 的直接实现:

          import itertools as it
          
          
          [x for x, y in it.zip_longest(temp1, temp2) if x != y]
          # ['Three', 'Four']
          

          【讨论】:

          • 只有当temp1temp2 中的元素排列良好时,itertools 解决方案才有效。例如,如果您翻转 temp2 中的元素或在 temp2 的开头插入一些其他值,则 listcomp 将只返回与 temp1 中相同的元素
          • 是的,这是这些方法的一个特点。如前所述,这些解决方案是保持顺序的——它们假定列表之间存在某种相对顺序。一个无序的解决方案是区分两组。
          【解决方案15】:

          这是另一种解决方案:

          def diff(a, b):
              xa = [i for i in set(a) if i not in b]
              xb = [i for i in set(b) if i not in a]
              return xa + xb
          

          【讨论】:

            【解决方案16】:

            如果对 difflist 的元素进行排序和设置,您可以使用简单的方法。

            list1=[1,2,3,4,5]
            list2=[1,2,3]
            
            print list1[len(list2):]
            

            或使用本机设置方法:

            subset=set(list1).difference(list2)
            
            print subset
            
            import timeit
            init = 'temp1 = list(range(100)); temp2 = [i * 2 for i in range(50)]'
            print "Naive solution: ", timeit.timeit('temp1[len(temp2):]', init, number = 100000)
            print "Native set solution: ", timeit.timeit('set(temp1).difference(temp2)', init, number = 100000)
            

            天真的解决方案:0.0787101593292

            原生集解:0.998837615564

            【讨论】:

              【解决方案17】:

              我在游戏中为时已晚,但您可以将上面提到的一些代码的性能与此进行比较,两个最快的竞争者是,

              list(set(x).symmetric_difference(set(y)))
              list(set(x) ^ set(y))
              

              我为初级编码表示歉意。

              import time
              import random
              from itertools import filterfalse
              
              # 1 - performance (time taken)
              # 2 - correctness (answer - 1,4,5,6)
              # set performance
              performance = 1
              numberoftests = 7
              
              def answer(x,y,z):
                  if z == 0:
                      start = time.clock()
                      lists = (str(list(set(x)-set(y))+list(set(y)-set(y))))
                      times = ("1 = " + str(time.clock() - start))
                      return (lists,times)
              
                  elif z == 1:
                      start = time.clock()
                      lists = (str(list(set(x).symmetric_difference(set(y)))))
                      times = ("2 = " + str(time.clock() - start))
                      return (lists,times)
              
                  elif z == 2:
                      start = time.clock()
                      lists = (str(list(set(x) ^ set(y))))
                      times = ("3 = " + str(time.clock() - start))
                      return (lists,times)
              
                  elif z == 3:
                      start = time.clock()
                      lists = (filterfalse(set(y).__contains__, x))
                      times = ("4 = " + str(time.clock() - start))
                      return (lists,times)
              
                  elif z == 4:
                      start = time.clock()
                      lists = (tuple(set(x) - set(y)))
                      times = ("5 = " + str(time.clock() - start))
                      return (lists,times)
              
                  elif z == 5:
                      start = time.clock()
                      lists = ([tt for tt in x if tt not in y])
                      times = ("6 = " + str(time.clock() - start))
                      return (lists,times)
              
                  else:    
                      start = time.clock()
                      Xarray = [iDa for iDa in x if iDa not in y]
                      Yarray = [iDb for iDb in y if iDb not in x]
                      lists = (str(Xarray + Yarray))
                      times = ("7 = " + str(time.clock() - start))
                      return (lists,times)
              
              n = numberoftests
              
              if performance == 2:
                  a = [1,2,3,4,5]
                  b = [3,2,6]
                  for c in range(0,n):
                      d = answer(a,b,c)
                      print(d[0])
              
              elif performance == 1:
                  for tests in range(0,10):
                      print("Test Number" + str(tests + 1))
                      a = random.sample(range(1, 900000), 9999)
                      b = random.sample(range(1, 900000), 9999)
                      for c in range(0,n):
                          #if c not in (1,4,5,6):
                          d = answer(a,b,c)
                          print(d[1])
              

              【讨论】:

                【解决方案18】:

                如果遇到TypeError: unhashable type: 'list',则需要将列表或集合转换为元组,例如

                set(map(tuple, list_of_lists1)).symmetric_difference(set(map(tuple, list_of_lists2)))
                

                另见How to compare a list of lists/sets in python?

                【讨论】:

                  【解决方案19】:

                  假设我们有两个列表

                  list1 = [1, 3, 5, 7, 9]
                  list2 = [1, 2, 3, 4, 5]
                  

                  我们可以从上面的两个列表中看到,list2中存在1、3、5项,而7、9项不存在。另一方面,list1 中存在第 1、3、5 项,而第 2、4 项则不存在。

                  返回包含项目 7、9 和 2、4 的新列表的最佳解决方案是什么?

                  以上所有答案都找到了解决方案,现在什么是最优化的?

                  def difference(list1, list2):
                      new_list = []
                      for i in list1:
                          if i not in list2:
                              new_list.append(i)
                  
                      for j in list2:
                          if j not in list1:
                              new_list.append(j)
                      return new_list
                  

                  def sym_diff(list1, list2):
                      return list(set(list1).symmetric_difference(set(list2)))
                  

                  使用timeit我们可以看到结果

                  t1 = timeit.Timer("difference(list1, list2)", "from __main__ import difference, 
                  list1, list2")
                  t2 = timeit.Timer("sym_diff(list1, list2)", "from __main__ import sym_diff, 
                  list1, list2")
                  
                  print('Using two for loops', t1.timeit(number=100000), 'Milliseconds')
                  print('Using two for loops', t2.timeit(number=100000), 'Milliseconds')
                  

                  返回

                  [7, 9, 2, 4]
                  Using two for loops 0.11572412995155901 Milliseconds
                  Using symmetric_difference 0.11285737506113946 Milliseconds
                  
                  Process finished with exit code 0
                  

                  【讨论】:

                    【解决方案20】:

                    arulmr解决方案的单行版本

                    def diff(listA, listB):
                        return set(listA) - set(listB) | set(listA) -set(listB)
                    

                    【讨论】:

                      【解决方案21】:

                      如果您想要更像变更集的东西...可以使用 Counter

                      from collections import Counter
                      
                      def diff(a, b):
                        """ more verbose than needs to be, for clarity """
                        ca, cb = Counter(a), Counter(b)
                        to_add = cb - ca
                        to_remove = ca - cb
                        changes = Counter(to_add)
                        changes.subtract(to_remove)
                        return changes
                      
                      lista = ['one', 'three', 'four', 'four', 'one']
                      listb = ['one', 'two', 'three']
                      
                      In [127]: diff(lista, listb)
                      Out[127]: Counter({'two': 1, 'one': -1, 'four': -2})
                      # in order to go from lista to list b, you need to add a "two", remove a "one", and remove two "four"s
                      
                      In [128]: diff(listb, lista)
                      Out[128]: Counter({'four': 2, 'one': 1, 'two': -1})
                      # in order to go from listb to lista, you must add two "four"s, add a "one", and remove a "two"
                      

                      【讨论】:

                        【解决方案22】:

                        我们可以计算交集减去列表的并集:

                        temp1 = ['One', 'Two', 'Three', 'Four']
                        temp2 = ['One', 'Two', 'Five']
                        
                        set(temp1+temp2)-(set(temp1)&set(temp2))
                        
                        Out: set(['Four', 'Five', 'Three']) 
                        

                        【讨论】:

                          【解决方案23】:

                          我更喜欢使用转换为集合,然后使用“difference()”函数。完整代码是:

                          temp1 = ['One', 'Two', 'Three', 'Four'  ]                   
                          temp2 = ['One', 'Two']
                          set1 = set(temp1)
                          set2 = set(temp2)
                          set3 = set1.difference(set2)
                          temp3 = list(set3)
                          print(temp3)
                          
                          

                          输出:

                          >>>print(temp3)
                          ['Three', 'Four']
                          

                          这是最容易理解的,而且如果您将来处理大数据,如果不需要重复,将其转换为集合将删除重复。希望它有所帮助;-)

                          【讨论】:

                          • 差异函数与接受答案中显示的 - 运算符相同,因此不确定这是否真的在 10 年后添加了任何新信息
                          【解决方案24】:

                          这可以用一行来解决。 问题给出了两个列表(temp1 和 temp2),它们在第三个列表(temp3)中返​​回它们的差异。

                          temp3 = list(set(temp1).difference(set(temp2)))
                          

                          【讨论】:

                            【解决方案25】:

                            这是@SuperNova的answer的修改版

                            def get_diff(a: list, b: list) -> list:
                                return list(set(a) ^ set(b))
                            

                            【讨论】:

                              【解决方案26】:

                              这里有一个简单的方法来区分两个列表(无论内容是什么),你可以得到如下所示的结果:

                              >>> from sets import Set
                              >>>
                              >>> l1 = ['xvda', False, 'xvdbb', 12, 'xvdbc']
                              >>> l2 = ['xvda', 'xvdbb', 'xvdbc', 'xvdbd', None]
                              >>>
                              >>> Set(l1).symmetric_difference(Set(l2))
                              Set([False, 'xvdbd', None, 12])
                              

                              希望这会有所帮助。

                              【讨论】:

                                【解决方案27】:

                                我知道这个问题已经得到了很好的答案,但我希望使用numpy 添加以下方法。

                                temp1 = ['One', 'Two', 'Three', 'Four']
                                temp2 = ['One', 'Two']
                                
                                list(np.setdiff1d(temp1,temp2))
                                
                                ['Four', 'Three'] #Output
                                

                                【讨论】:

                                  【解决方案28】:

                                  如果您应该从列表 a 中删除所有值,这些值存在于列表 b 中。

                                  def list_diff(a, b):
                                      r = []
                                  
                                      for i in a:
                                          if i not in b:
                                              r.append(i)
                                      return r
                                  

                                  list_diff([1,2,2], [1])

                                  结果:[2,2]

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

                                  【讨论】:

                                    【解决方案29】:

                                    您可以循环浏览第一个列表,对于不在第二个列表中但在第一个列表中的每个项目,将其添加到第三个列表中。例如:

                                    temp3 = []
                                    for i in temp1:
                                        if i not in temp2:
                                            temp3.append(i)
                                    print(temp3)
                                    

                                    【讨论】:

                                      【解决方案30】:
                                      def diffList(list1, list2):     # returns the difference between two lists.
                                          if len(list1) > len(list2):
                                              return (list(set(list1) - set(list2)))
                                          else:
                                              return (list(set(list2) - set(list1)))
                                      

                                      例如如果list1 = [10, 15, 20, 25, 30, 35, 40]list2 = [25, 40, 35] 则返回的列表将是output = [10, 20, 30, 15]

                                      【讨论】:

                                      • 差异操作不能这样。即使在整数的情况下,如果你告诉一个函数执行'a - b',它应该只从'a'中减去'b',不管'b'是否大于'a'或其他。列表和集合的情况类似。 A - B 和 B - A 都可以是有效操作,无论 A 和 B 的长度如何,您只需要从 A 中排除 B 的内容即可执行 A - B。
                                      猜你喜欢
                                      • 1970-01-01
                                      • 2020-10-30
                                      • 2019-05-12
                                      • 2018-06-22
                                      • 1970-01-01
                                      • 2013-11-14
                                      • 2014-10-09
                                      相关资源
                                      最近更新 更多