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

Deo*_*eon 203 python

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

>>> a = [2,3,4]
>>> print (1 or 2) in a
False
>>> print (2 or 1) in a
True
Run Code Online (Sandbox Code Playgroud)

Joe*_*erg 243

>>> 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])
Run Code Online (Sandbox Code Playgroud)

空列表和空集都是False,因此您可以直接将该值用作真值.

  • FWIW - 我进行了速度比较,这里提供的第一个解决方案是到目前为止禁食. (12认同)
  • 交叉点的想法给了我这个想法.return len(set(a).intersection(set(b))) (4认同)
  • @user89788 使用生成器的答案再次快得多,因为只要找到一个“True”值,“any”就可以尽早返回——它不必先构建整个列表 (3认同)
  • `bool(S1&S2)` (2认同)

小智 199

啊,托比亚斯,你打败了我.我在考虑你的解决方案的这种微小变化:

>>> a = [1,2,3,4]
>>> b = [2,7]
>>> print(any(x in a for x in b))
True
Run Code Online (Sandbox Code Playgroud)

  • @LukeSapan:你是对的.该订单可以通过"print any(x in max(a,b,key = len)for x in min(a,b,key = len))"获得.这简单地使用x in long for x. (10认同)
  • 我意识到这是一个非常古老的答案,但是如果一个列表很长而另一个列表很短,那么是否有一个订单会产生更快的性能?(即,`x in long for x in short` vs`x in short for x in long`) (5认同)
  • @Nuclearman,注意:如果两个列表'a`和`b`的长度相同,则max和min将返回最左边的列表,这使得`any()`调用在两侧的同一列表上运行.如果你绝对需要检查长度,请在第二次调用中颠倒列表的顺序:`any(x in max(a,b,key = len)for x in(b,a,key = len))`. (4认同)
  • @NoahBogart你是对的,这个解决方案似乎和任何解决方案一样好.我还假设你的意思是:`任意(x in max(a,b,key = len)x in min(b,a,key = len))`(错过最小值). (3认同)
  • 这是最好的答案,因为它使用了一个生成器,并且一旦找到匹配就会返回(正如其他人所说的那样,只是没有这个答案!). (2认同)

小智 29

也许有点懒惰:

a = [1,2,3,4]
b = [2,7]

print any((True for x in a if x in b))
Run Code Online (Sandbox Code Playgroud)

  • @BastienLéonard...除了它更快,因为它使用了一个生成器,因此`any`可以提前返回,而你的版本必须在"any"可以使用它之前从理解构建整个列表.@ user89788的答案略胜一筹,因为双括号是不必要的 (5认同)

Den*_*gan 17

想想代码实际上说的是什么!

>>> (1 or 2)
1
>>> (2 or 1)
2
Run Code Online (Sandbox Code Playgroud)

这应该可以解释一下.:) Python显然实现了"懒惰或",这应该不足为奇.它执行这样的事情:

def or(x, y):
    if x: return x
    if y: return y
    return False
Run Code Online (Sandbox Code Playgroud)

在第一个例子中,x == 1y == 2.在第二个例子中,反之亦然.这就是为什么它根据它们的顺序返回不同的值.


005*_*005 14

a = {2,3,4}
if {1,2} & a:
    pass
Run Code Online (Sandbox Code Playgroud)

代码高尔夫版.如果有意义,请考虑使用集合.我发现这比列表理解更具可读性.


Him*_*Das 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
Run Code Online (Sandbox Code Playgroud)


Bas*_*ard 6

我能想到的最好:

any([True for e in (1, 2) if e in a])
Run Code Online (Sandbox Code Playgroud)


Dan*_*aun 6

在python 3中,我们可以开始使用解包星号。给出两个列表:

bool(len({*a} & {*b}))
Run Code Online (Sandbox Code Playgroud)

编辑:纳入 alkanen 的建议


dan*_*ton 5

当您认为“检查 a 是否在 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)))
Run Code Online (Sandbox Code Playgroud)

当您要检查的项目数量很少时,差异可以忽略不计。但是根据一个大列表检查大量数字......

测试:

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)
Run Code Online (Sandbox Code Playgroud)

速度:

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
Run Code Online (Sandbox Code Playgroud)

始终快速的方法是制作一组(列表中的),但交集在大数据集上效果最好!