3

I need to compare two lists without taking their order into account:

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

when I try to compare them, it returns False:

>>> list_a == list_b
False

Both lists have many elements, what would be the optimal way to compare them?

Naglis
  • 2,583
  • 1
  • 19
  • 24
Dayana
  • 1,500
  • 1
  • 16
  • 29

3 Answers3

12

You need to compare whether both lists result in the same 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

Another solution would be to sort both lists and then compare them. The Counter approach should be more efficient for big lists since it has linear time complexity (i.e. O(n)) while sorting is only pseudo-linear (i.e. O(n*log(n)).

timgeb
  • 76,762
  • 20
  • 123
  • 145
  • 1
    I tried it and it worked perfectly. I think this is the most efficient way to do it. Thank you! – Dayana Sep 07 '17 at 12:58
6

One way would be to compare a set of each list

>>> list_a = ['one', 'two', 'three']
>>> list_b = ['three', 'one', 'two']
>>> set(list_a) == set(list_b)
True

Otherwise if there may be duplicates, and you want to ensure they have the same number of each element then you could do

>>> sorted(list_a) == sorted(list_b)
True
Cory Kramer
  • 114,268
  • 16
  • 167
  • 218
  • Thank you very much for the answer. I tried it and it worked perfectly! – Dayana Sep 07 '17 at 12:57
  • 1
    This can actually lead to false positives: `list_a = ["a", "a", b"] ; list_b = ["a", "b", "b"] ; set(list_a) == set(list_b) # True` – Glutexo Aug 14 '19 at 14:45
1

Counter of module collections will be the way to go. As you have strings and as show in the answers:

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

if the list have any unhashable elements (other than string and number), like objects etc, you might want to take out their id and make another list and compare their Counter.

...
if Counter(map(id,list_a)) == Counter(map(id,list_b)):
    print "same unhashable things in list_a and list_b"
harshil9968
  • 3,254
  • 1
  • 16
  • 26