如何比较两个顺序不同的列表?

3

我需要比较两个列表,但不考虑它们的顺序:

list_a = ['one', 'two', 'three']
list_b = ['three', 'one', 'two']

当我尝试比较它们时,它返回False

>>> list_a == list_b
False

两个列表都有很多元素,最优的比较方法是什么?


4
先把它们分类吗? - wwii
3个回答

12

你需要比较两个列表的 Counter 是否相同。

>>> from collections import Counter
>>> list_a = ['one', 'two', 'three']
>>> list_b = ['three', 'one', 'two']
>>> Counter(list_a) == Counter(list_b)
True
>>> list_b = ['three', 'one', 'two', 'two']
>>> Counter(list_a) == Counter(list_b)
False
>>> set(list_a) == set(list_b)
True # False positive

另一个解决方案是对两个列表进行排序,然后进行比较。在处理大型列表时,Counter方法应该更加高效,因为它具有线性时间复杂度(即O(n)),而排序只有伪线性时间复杂度(即O(n*log(n)))。


1
我试过了,完美地运行了。我认为这是最有效的方法。谢谢! - Dayana

6
一种方法是比较每个列表的set
>>> list_a = ['one', 'two', 'three']
>>> list_b = ['three', 'one', 'two']
>>> set(list_a) == set(list_b)
True

否则,如果可能存在重复项,并且您希望确保它们具有相同数量的每个元素,则可以执行以下操作:
>>> sorted(list_a) == sorted(list_b)
True

非常感谢您的答复。我尝试了一下,它完美地工作了! - Dayana
1
这实际上可能导致误报:list_a = ["a", "a", b"] ; list_b = ["a", "b", "b"] ; set(list_a) == set(list_b) # True - Glutexo

1

collections 模块中的 Counter 将是解决问题的方法。由于您有字符串并且如答案所示:

from collections import Counter
.....
if Counter(list_a) == Counter(list_b): # True or False

如果列表中有任何不可哈希的元素(除了字符串和数字之外),例如对象等,则您可能需要取出它们的ID并创建另一个列表,并比较它们的计数器。
...
if Counter(map(id,list_a)) == Counter(map(id,list_b)):
    print "same unhashable things in list_a and list_b"

非常感谢您的回答。它也起作用了。 - Dayana

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