1

如何在 python 中使用列表理解来比较两个数组是否具有相同的元素?

我做了以下事情:

>>> aa=[12,3,13];
>>> bb=[3,13,12];
>>> pp=[True for x in aa for y in bb if y==x]
>>> pp
[True, True, True]
>>> bb=[3,13,123];
>>> pp=[True for x in aa for y in bb if y==x]
[True, True]

如果不是真的,我也想输出 False,而不是像后一种情况那样只输出两个真,但不知道该怎么做。

最后,我想得到一个 True/False 值(如果所有都为 true,则为 true,如果其中一个为 false,则为 false)而不是 true 和/或 false 的列表。我知道迭代 pp(true 和 false 列表) 的简单循环就足够了,但我相信还有更多的 Pythonic 方式。

4

3 回答 3

7

您正在针对另一个列表的每个元素测试每个列表的每个元素,找到所有True. 除了效率低下,这也是不正确的做法。

请改用成员资格测试,并查看所有这些测试都True使用以下all()功能:

all(el in bb for el in aa)

all()True如果您给它的可迭代对象的每个元素都是 ,则返回TrueFalse否则。

这并不能完全测试列表是否等效;您还需要测试长度:

len(aa) == len(bb) and all(el in bb for el in aa)

为了使更长的bb列表更有效;set()首先从该列表创建一个:

def equivalent(aa, bb):
    if len(aa) != len(bb):
        return False
    bb_set = set(bb)
    return all(el in bb_set for el in aa)

这仍然不能很好地处理重复数字;[1, 1, 2]相当于[1, 2, 2]用这种方法。你没有明确说明在这种极端情况下应该发生什么;唯一严格的等效测试是对两个输入进行排序:

len(aa) == len(bb) and sorted(aa) == sorted(bb)

我们首先测试长度以避免在长度不同的情况下进行排序。

如果允许重复,无论输入的长度如何,您都可以完全放弃循环而只使用集合:

not set(aa).symmetric_difference(bb)

测试它们是否具有相同的独特元素。

于 2013-10-21T15:31:29.533 回答
2
set(aa) == set(bb)

这具有相同的效果,但可能会稍快一些

not set(aa).symmetric_difference(bb)

如果你需要[1,1]不等同于[1]

sorted(aa) == sorted(bb)
于 2013-10-21T15:35:10.040 回答
1

“你正在测试每个列表的每个元素与另一个列表的每个元素,找到所有为真的组合。除了效率低下,这也是不正确的方法。”

我同意上面的说法,下面的代码False也列出了这些值,但我认为你真的不需要这个。

>>> bp = [y==x for x in aa for y in bb]
[False, False, True, True, False, False, False, True, False]

>>> False in bp
True
于 2013-10-21T15:37:45.973 回答