我正在尝试找一个简短的方法来查看列表中是否有以下任何项目,但我的第一次尝试不起作用。除了编写一个完成此功能的函数之外,还可以检查列表中是否有多个项目。
>>> a = [2,3,4]
>>> print (1 or 2) in a
False
>>> print (2 or 1) in a
True
答案 0 :(得分:223)
>>> L1 = [2,3,4]
>>> L2 = [1,2]
>>> [i for i in L1 if i in L2]
[2]
>>> S1 = set(L1)
>>> S2 = set(L2)
>>> S1.intersection(S2)
set([2])
空列表和空集都是False,因此您可以直接将该值用作真值。
答案 1 :(得分:181)
>>> a = [1,2,3,4]
>>> b = [2,7]
>>> print(any(x in a for x in b))
True
答案 2 :(得分:25)
也许有点懒:
a = [1,2,3,4]
b = [2,7]
print any((True for x in a if x in b))
答案 3 :(得分:16)
想想代码实际上说的是什么!
>>> (1 or 2)
1
>>> (2 or 1)
2
这应该可以解释一下。 :) Python显然实现了“懒惰或”,这应该不足为奇。它执行类似这样的事情:
def or(x, y):
if x: return x
if y: return y
return False
在第一个示例中,x == 1
和y == 2
。在第二个例子中,反之亦然。这就是为什么它会根据它们的顺序返回不同的值。
答案 4 :(得分:13)
a = {2,3,4}
if {1,2} & a:
pass
代码高尔夫版。如果有意义,请考虑使用集合。 我觉得这比列表理解更具可读性。
答案 5 :(得分:12)
没有列表推导的1行。
>>> any(map(lambda each: each in [2,3,4], [1,2]))
True
>>> any(map(lambda each: each in [2,3,4], [1,5]))
False
>>> any(map(lambda each: each in [2,3,4], [2,4]))
True
答案 6 :(得分:5)
我能想到的最好:
any([True for e in (1, 2) if e in a])
答案 7 :(得分:4)
当你想“检查是否在b中”时,想想哈希(在这种情况下,设置)。最快的方法是对要检查的列表进行哈希处理,然后检查其中的每个项目。
这就是Joe Koberg的答案很快的原因:检查集合交叉点非常快。
如果你没有大量的数据,制作套装可能是浪费时间。因此,您可以创建一组列表并检查每个项目:
tocheck = [1,2] # items to check
a = [2,3,4] # the list
a = set(a) # convert to set (O(len(a)))
print [i for i in tocheck if i in a] # check items (O(len(tocheck)))
当您要检查的项目数量很少时,差异可以忽略不计。但是要根据大量清单检查大量数字......
测试:
from timeit import timeit
methods = ['''tocheck = [1,2] # items to check
a = [2,3,4] # the list
a = set(a) # convert to set (O(n))
[i for i in tocheck if i in a] # check items (O(m))''',
'''L1 = [2,3,4]
L2 = [1,2]
[i for i in L1 if i in L2]''',
'''S1 = set([2,3,4])
S2 = set([1,2])
S1.intersection(S2)''',
'''a = [1,2]
b = [2,3,4]
any(x in a for x in b)''']
for method in methods:
print timeit(method, number=10000)
print
methods = ['''tocheck = range(200,300) # items to check
a = range(2, 10000) # the list
a = set(a) # convert to set (O(n))
[i for i in tocheck if i in a] # check items (O(m))''',
'''L1 = range(2, 10000)
L2 = range(200,300)
[i for i in L1 if i in L2]''',
'''S1 = set(range(2, 10000))
S2 = set(range(200,300))
S1.intersection(S2)''',
'''a = range(200,300)
b = range(2, 10000)
any(x in a for x in b)''']
for method in methods:
print timeit(method, number=1000)
速度
M1: 0.0170331001282 # make one set
M2: 0.0164539813995 # list comprehension
M3: 0.0286040306091 # set intersection
M4: 0.0305438041687 # any
M1: 0.49850320816 # make one set
M2: 25.2735087872 # list comprehension
M3: 0.466138124466 # set intersection
M4: 0.668627977371 # any
持续快速的方法是制作一组(列表中的),但交叉点对大数据集的效果最好!
答案 8 :(得分:4)
在python 3中,我们可以开始使用解包星号。给出两个列表:
any({*a} & {*b})
答案 9 :(得分:3)
在某些情况下(例如,唯一列表元素),可以使用集合操作。
>>> a=[2,3,4]
>>> set(a) - set([2,3]) != set(a)
True
>>>
或者,使用set.isdisjoint(),
>>> not set(a).isdisjoint(set([2,3]))
True
>>> not set(a).isdisjoint(set([5,6]))
False
>>>
答案 10 :(得分:2)
这将在一行中完成。
>>> a=[2,3,4]
>>> b=[1,2]
>>> bool(sum(map(lambda x: x in b, a)))
True
答案 11 :(得分:0)
我不得不说我的处境可能不是您想要的,但它可能为您的思考提供了另一种选择。
我已经尝试了set()和any()方法,但是仍然存在速度问题。因此,我记得Raymond Hettinger所说的python中的所有内容都是字典,并尽可能使用dict。这就是我尝试过的。
我使用带有int的defaultdict表示否定结果,并将第一个列表中的项目用作第二个列表的键(转换为defaultdict)。因为您可以使用dict进行即时查找,所以您会立即知道默认dict中是否存在该项目。我知道您并不总是可以更改第二个列表的数据结构,但是如果您能够从一开始就这样做,那么它的速度会更快。您可能需要将list2(较大的列表)转换为defaultdict,其中key是您要从小列表中检查的潜在值,值是1(命中)或0(无命中,默认)。
from collections import defaultdict
already_indexed = defaultdict(int)
def check_exist(small_list, default_list):
for item in small_list:
if default_list[item] == 1:
return True
return False
if check_exist(small_list, already_indexed):
continue
else:
for x in small_list:
already_indexed[x] = 1
答案 12 :(得分:-1)
print (1 in a) or (2 in a)
print (2 in a) or (5 in a)
这是一个非常古老的问题,但我对任何答案都不满意,所以为了后人的缘故,我不得不加上这个。
答案 13 :(得分:-3)
简单。
_new_list = []
for item in a:
if item in b:
_new_list.append(item)
else:
pass