我在Python中有两个列表:

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

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

temp3 = ['Three', 'Four']

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


当前回答

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

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

其他回答

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

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

如果您真的关注性能,那么使用numpy!

以下是github上的完整笔记本,并对list、numpy和pandas进行了比较。

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

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

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

这可能比马克的清单理解还要快:

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

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

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

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