我在Python中有两个列表:

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

假设每个列表中的元素都是唯一的,我想用第一个列表中的项创建第三个列表,这些项不在第二个列表中:

temp3 = ['Three', 'Four']

有没有没有周期和检查的快速方法?


当前回答

如果列表是对象而不是基本类型,这是一种方法。

代码更加明确,并给出了一个副本。 这可能不是一个有效的实现,但对于较小的对象列表来说是干净的。

a = [
    {'id1': 1, 'id2': 'A'},
    {'id1': 1, 'id2': 'B'},
    {'id1': 1, 'id2': 'C'},  # out
    {'id1': 2, 'id2': 'A'},
    {'id1': 2, 'id2': 'B'},  # out
]
b = [
    {'id1': 1, 'id2': 'A'},
    {'id1': 1, 'id2': 'B'},
    {'id1': 2, 'id2': 'A'},
]


def difference(a, b):
  for x in a:
    for y in b:
      if x['id1'] == y['id1'] and x['id2'] == y['id2']:
        x['is_removed'] = True

  c = [x for x in a if not x.get('is_removed', False)]
  return c


print(difference(a, b))

其他回答

两个列表(例如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)

or

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文档参考

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

Code

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

这假设两个列表包含相同开头的字符串。更多细节请参阅文档。注意,与set操作相比,它不是特别快。


使用itertools.zip_longest的直接实现:

import itertools as it


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

最简单的方法,

使用设置().difference(设置())

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

答案设置([1])

可以打印为列表,

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

你可以使用列表推导式:

temp3 = [item for item in temp1 if item not in temp2]

这里有一个最简单情况的反答案。

这比上面那个做双向差分的要短,因为它只做了问题要求的事情:生成第一个列表中的东西的列表,而不是第二个列表中的东西。

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