我在Python中有两个列表:
temp1 = ['One', 'Two', 'Three', 'Four']
temp2 = ['One', 'Two']
假设每个列表中的元素都是唯一的,我想用第一个列表中的项创建第三个列表,这些项不在第二个列表中:
temp3 = ['Three', 'Four']
有没有没有周期和检查的快速方法?
我在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))
其他回答
这可以用一行来解决。 问题给出两个列表(temp1和temp2),在第三个列表(temp3)中返回它们的差值。
temp3 = list(set(temp1).difference(set(temp2)))
如果您真的关注性能,那么使用numpy!
以下是github上的完整笔记本,并对list、numpy和pandas进行了比较。
https://gist.github.com/denfromufa/2821ff59b02e9482be15d27f2bbd4451
试试这个:
temp3 = set(temp1) - set(temp2)
如果您想要更类似于变更集的东西……可以使用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"
我想要一个能够使用两个列表并能做diff in bash所做的事情的东西。因为当你搜索“python diff two lists”时,这个问题首先会弹出,而且不是很具体,所以我会把我想到的贴出来。
使用difflib中的SequenceMather,你可以像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']
当然,如果您的应用程序做出了与其他答案相同的假设,那么您将从中受益最大。但如果你正在寻找一个真正的差异功能,那么这是唯一的方法。
例如,其他答案都无法处理:
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]