检查两个列表是否至少共享一个元素

4

我有两个列表,例如:

a = ["mail1", "mail2", "mail3", "mail4"]
b = ["mail2", "mail5"]

我想要检查列表b中的任何元素是否也出现在列表a中。

我想知道是否有一种不需要使用for循环的方法(以及是什么方法)来做到这一点。

另外,我想知道如何创建一个布尔值列表,其中每个值将是值a[i]b[i]比较的结果,类似于:

[z for i, j in zip(a, b)  z = i == j] # (just with the right syntax)

如果在某个位置上i == j,则z将为1,因此我可以检查数组中是否存在任何“True”值。

请问您在Python方面尝试了什么?提供一些代码会更方便! - ρss
请每个帖子只提出一个问题。您的第一个问题可以使用sets来回答。您的第二个问题已经接近成功:[i == j for i, j in zip(a, b)],但这将限制于两个列表中最短的长度。例如,它将返回[False, False] - Martijn Pieters
3个回答

12
你可以使用 任何
any(x in a for x in b)

这个生成器表达式的好处是,只要生成器产生了一个Trueany函数就会立即返回True,也就是说不会有冗余的x in a查找。

编辑:

你可以通过将a转换为一个集合来提高时间复杂度。

a_set = set(a)
any(x in a_set for x in b)

关于您的新问题:

[x == y for x,y in zip(a,b)]

任何函数的实际语法是什么?我尝试将其用作return any(x in a for x in b);,但它报告缺少')'、标识符和分号。 - Bobys
1
@Bobys any 接受一个可迭代对象,并检查该可迭代对象中的任何元素是否为真(即 bool(element) == True)。你的语句在语法上是正确的(可迭代对象是生成器表达式),因此你得到的错误必须来自其他地方。 - timgeb

9

一种优雅的方法是使用集合:

a = ["mail1", "mail2", "mail3", "mail4"]
b = ["mail2", "mail5"]

anb = set(a) & set(b)

print anb

if anb:
    print True

>>> set(['mail2'])
>>> True

1
从非平凡列表构建两个集合(在大多数情况下)肯定比在any中运行genexp需要更长的时间来构建。 - Adam Smith
1
当然可以,这只是一种聪明的方法来获取差异并进行检查。我只是想展示它,因为太多人不知道集合有多棒。 - dt0xff

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接