如何检查列表中是否有以下项目之一?

时间:2009-04-11 15:13:08

标签: python

我正在尝试找一个简短的方法来查看列表中是否有以下任何项目,但我的第一次尝试不起作用。除了编写一个完成此功能的函数之外,还可以检查列表中是否有多个项目。

>>> a = [2,3,4]
>>> print (1 or 2) in a
False
>>> print (2 or 1) in a
True

14 个答案:

答案 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 == 1y == 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