我正在编写一些python
代码,我必须检查list2
中是否存在list1
中的所有值,我是通过使用set(list2).difference(list1)
做到的,但是功能太慢,列表中有很多项目。
所以我认为list1
可能是快速查找的字典......
所以我想找到一种快速的方法来阻止列表中是否有一个不属于字典的项目
表现明智的是
之间有什么区别d = {1: 1, 2:2, 3:3}
l = [3, 4, 5]
for n in l:
if not n in d:
do_stuff
VS
for n in l:
if not d[n]:
do_stuff
并且如果这些都是垃圾并且你知道更快的话,请告诉我。
Edit1:list1或d可以包含不在list2中但不是相反的元素。
答案 0 :(得分:3)
实现目标的快捷方法是使用all
和生成器理解。
s_list2 = set(list2)
all_present = all(l in s_list2 for l in list1)
在list2中不存在list1的某些元素的情况下,这将是有利的。
有些时间。如果第一个列表中的所有值都包含在第二个列表中:
In [4]: l1 = range(100)
In [5]: l2 = range(1000)
In [6]: random.shuffle(l1)
In [9]: random.shuffle(l2)
In [20]: %timeit s2 = set(l2); all(l in s2 for l in l1)
10000 loops, best of 3: 26.4 us per loop
In [21]: %timeit s1 = set(l1); s2 = set(l2); s1.issubset(s2)
10000 loops, best of 3: 25.3 us per loop
如果我们看一下第一个列表中的某些值在第二个列表中不的情况:
In [2]: l1 = range(1000)
In [3]: l2 = range(100)
In [4]: random.shuffle(l1)
In [5]: random.shuffle(l2)
In [6]: sl2 = set(l2)
In [8]: %timeit ss = set(l2); set(l1) & ss == ss
10000 loops, best of 3: 27.8 us per loop
In [10]: %timeit s1 = set(l1); s2 = set(l2); s2.issubset(s1)
10000 loops, best of 3: 24.7 us per loop
In [11]: %timeit sl2 = set(l2); all(l in sl2 for l in l1)
100000 loops, best of 3: 3.58 us per loop
你可以看到这种方法在第一种情况下与issubset
的性能相当,在第二种情况下更快,因为它会短路并且不需要构造2个中间集(只需要一个)
有一个大型列表和一个小型列表证明了gencomp方法的好处:
In [7]: l1 = range(10)
In [8]: l2 = range(10000)
In [9]: %timeit sl2 = set(l2); all(l in sl2 for l in l1)
1000 loops, best of 3: 230 us per loop
In [10]: %timeit sl1 = set(l1); all(l in sl1 for l in l2)
1000000 loops, best of 3: 1.45 us per loop
In [11]: %timeit s1 = set(l1); s2 = set(l2); s1.issubset(s2)
1000 loops, best of 3: 228 us per loop
In [12]: %timeit s1 = set(l1); s2 = set(l2); s2.issubset(s1)
1000 loops, best of 3: 228 us per loop
答案 1 :(得分:2)
您可以将列表转换为集合,然后使用方法issubset()
检查一个是否是另一个集合的子集。
In [78]: import random
In [79]: lis2=range(100)
In [80]: random.shuffle(lis2)
In [81]: lis1=range(1000)
In [82]: random.shuffle(lis1)
In [83]: s1=set(lis1)
In [84]: all(l in s1 for l in lis2)
Out[84]: True
In [85]: %timeit all(l in s1 for l in lis2)
10000 loops, best of 3: 28.6 us per loop
In [86]: %timeit s2=set(lis2);s2.issubset(s1)
100000 loops, best of 3: 12 us per loop
In [87]: s2.issubset(s1)
Out[87]: True
答案 2 :(得分:1)
对两个列表进行排序然后一起遍历它们是O(n log n)。即:
l1.sort()
l2.sort()
j = 0
for i in range(0,len(l1)):
while ((j < len(l2)) and (l1[i] == l2[j])):
j = j+1
if (j == len(l2)):
break
if (l1[i] > l2[j]):
break
if (j == len(l2)): # all of l2 in l1
现在就时间复杂度来说,就像我说的那样是O(n log n)因为排序(第二个循环小于O(n))。然而,它在python中可能不比内置集合操作更快。你必须尝试一下。
[顺便说一句,如果我考虑的话,可能是一种更加灵巧的方式来完成最后一部分的理解]