2014-02-07 204 views
1

好吧,我有两个列表,列表1和列表2.我想查找列表1和列表2中的所有项目,并将它们从列表1中删除。我们曾想过这样做是循环遍历清单1,然后循环遍历清单2,看它是否在清单2中,但在放大时似乎很慢并且效率低下。有没有更有效的方法来做到这一点?比较两个列表 - Python

此外,这些列表将按字母顺序排列(它们是字符串),如果这有帮助的话。

我正在使用Python,但我也想从一般编程的角度思考。

list1 = ['bar','foo','hello','hi'] 
list2 = ['alpha','bar','hello','xam'] 

列表1将成为['foo','hi']

+1

你可以使用'sets' – bnjmn

回答

6

在Python中,你可能会想用一组:

intersection = set(list1).intersection(list2) 

这将返回一个set这破坏了订单(除其他事项外)但您随时可以使用该设置来过滤list1

list1 = [x for x in list1 if x not in intersection] 

如果您真的想使用该集合,则该交集是最有用的。

set2 = set(list2) 
list1 = [x for x in list1 if x not in set2] 
+0

运用问题输出样本,这给了'''设置([ '酒吧', '你好'])'''这是不什么海报想要。这个版本是否依赖? (我在2.7.6?) – wnnmaw

+0

实际上,你不需要交集,因为你循环的所有元素都来自'list1'。 –

+0

@wnnmaw - 我最初误解了OP的问题。我更新了在list-comp中添加'not'来获得预期的输出。 – mgilson

4

使用set得到两者之间的区别:

list1 = ['bar','foo','hello','hi'] 
list2 = ['alpha','bar','hello','xam'] 

set1 = set(list1) 
set2 = set(list2) 
set1 - set2 

输出:

正如评论指出的那样,如果你不想一组在所有这不是确有必要
set(['hi', 'foo']) 

如上所述通过@chepner,使用set.difference,只有第一个需要被转换成一组

set1.difference(list2) 

如果顺序很重要,使他们的一个一组,并对比其他反对:

set2 = set(list2) 
[x for x in list1 if x not in set2] 

输出:

['foo', 'hi'] 
+1

'-'是'差异'方法的运算符形式,因此您可以使用'set(list1).difference(list2)'来避免额外遍历'list2'。 – chepner

+0

谢谢,为此编辑。但不幸的是你不能做'set - list' – mhlester

1

下面是一个使用通用的解决方案编程方法,不使用集合,并没有特别优化。它依赖于正在排序的两个列表。

list1 = ['a', 'b', 'd', 'f', 'k'] 
list2 = ['c', 'd', 'i'] 
result = [] 

i1 = 0 
i2 = 0 
while i1 < len(list1) and i2 < len(list2): 
    # invariants: 
    # list1[i1] not in list2[:i2], and 
    # result == (list1[:i1] with elements of list2[:i2] omitted) 
    # 
    if list1[i1] < list2[i2]: 
     # By assumption, list1[i1] not in list2[:i2], 
     # and because list2 is sorted, the true 'if' condition 
     # implies that list1[i1] isn't in list2[i2:] either; 
     # that is, it isn't in list2 at all. 
     result.append(list1[i1]) 
     i1 += 1 
    elif list1[i1] > list2[i2]: 
     # can't decide membership of list1[i1] yet; 
     # advance to next element of list2 and loop again 
     i2 += 1 
    else: 
     # list1[i1] == list2[i2], so omit this element 
     i1 += 1 
     i2 += 1 

# Add any remaining elements of list1 to tail of result 
if i1 < len(list1): 
    result.extend(list1[i1:]) 

print(result) 

结果: ['a', 'b', 'f', 'k']