Pythonic方法通过验证存在

时间:2017-05-16 00:34:03

标签: python list list-comprehension

从另一个列表中减去一个列表的一种好的pythonic方法是使用列表推导:

# remove all elements of list2 from list1
list1 = [x for x in list1 if x not in list2]

我可以在同一次迭代中检查list2本身是否只包含来自list1的元素而不单独迭代list2吗?

2 个答案:

答案 0 :(得分:2)

如果您只需要显式迭代一次,则可以从list1中的list2(或其副本)中删除内容。请记住,无论如何inremove都会遍历list2。

list_delta = []
for x in list1:
    if x not in list2:
        list_delta.append(x)
    else:
        list2.remove(x)
if list2:
    print(list2) # list2 now contains only elements not list1
else:
    pass # list2 is empty, thus contains no elements that aren't in list1

然而,显式迭代两次将具有几乎相同的时间复杂度,而更加pythonic。

list1 = [x for x in list1 if x not in list2]
presence = not any(x for x in list2 if x not in list1)
# presence is true if list2 only contains elements from list1

原来误解了下面的答案

您无需检查。根据定义,x必须在list1中,否则迭代器不会提供它(因为你正在迭代list1项目)

但是如果你在迭代时可能会被修改(这种情况你应该绝对避免):

list1 = [x for x in list1 if x not in list2 and x in list1]

如果您需要更复杂的行为,例如显示错误消息,请使用显式循环

list_delta = []
for x in list1:
    if x not in list1:
        raise IndexError("oh god what")
    if x not in list2:
        list_delta.append(x)

但说实话,这似乎是X-Y problem,因为你永远不必这样做

答案 1 :(得分:0)

我不确定我理解你在那里问的是什么,但如果顺序无关紧要且没有重复,你可以使用设置差异作为评论中提到的@ Chih-Hsu Jack Lin:

list(set(list1) - set(list2))

如果顺序无关紧要,但元素计数确实很重要,另一种方法是使用collections.Counter

list((Counter(list1) - Counter(list2)).elements())