# Re: best way to compare contents of 2 lists?

Discussion in 'Python' started by Esmail, Apr 24, 2009.

1. ### EsmailGuest

David Robinow wrote:
> On Thu, Apr 23, 2009 at 9:31 PM, Esmail <> wrote:
>> What is the best way to compare the *contents* of two different
>> lists regardless of their respective order? The lists will have
>> the same number of items, and be of the same type.
>>
>> E.g. a trivial example (my lists will be larger),
>>
>> a=[1, 2, 3]
>>
>> b=[2, 3, 1]
>>
>> should yield true if a==b
>>
>> I suppose I could sort them and then compare them. I.e.,
>>
>> sorted(a)==sorted(b)
>>
>>
>> I am wondering if there is a more efficient/preferred way to do so.
>>
>> Thanks,
>> Esmail
>>
>> --
>> http://mail.python.org/mailman/listinfo/python-list
>>

>
> set(a) == set(b) # test if a and b have the same elements
>
> # check that each list has the same number of each element
> # i.e. [1,2,1,2] == [1,1,2,2], but [1,2,2,2] != [1,1,1,2]
> for elem in set(a):
> a.count(elem) == b.count(elem)

Ah .. this part would take care of different number of duplicates
in the lists. Cool.

thanks,
Esmail

Esmail, Apr 24, 2009

2. ### John YeungGuest

Esmail <> wrote:
> What is the best way to compare the *contents* of two different
> lists regardless of their respective order? The lists will have
> the same number of items, and be of the same type.

"Best" can mean different things. Fastest? Shortest code? Most

> David Robinow wrote:
> > set(a) == set(b)    # test if a and b have the same elements

>
> > # check that each list has the same number of each element
> > # i.e.    [1,2,1,2] == [1,1,2,2], but [1,2,2,2] != [1,1,1,2]
> > for elem in set(a):
> >   a.count(elem) == b.count(elem)

>
> Ah .. this part would take care of different number of duplicates
> in the lists. Cool.

It takes care of the duplicates, but so does your initial solution,
which I like best:

> sorted(a)==sorted(b)

This is concise, clear, and in my opinion, the most Pythonic. It may
well even be the fastest. (If you didn't have to match up the numbers
of duplicates, the set solution would be most Pythonic and probably
fastest.)

John

John Yeung, Apr 24, 2009

3. ### Piet van OostrumGuest

>>>>> John Yeung <> (JY) wrote:

>JY> It takes care of the duplicates, but so does your initial solution,
>JY> which I like best:

>>> sorted(a)==sorted(b)

>JY> This is concise, clear, and in my opinion, the most Pythonic. It may
>JY> well even be the fastest. (If you didn't have to match up the numbers
>JY> of duplicates, the set solution would be most Pythonic and probably
>JY> fastest.)

But it may fail if the list cannot be sorted because it contains
incomparable elements:

>>> a = [1, 2, 3+4j]
>>> b = [2, 3+4j, 1]
>>> set(a) == set(b)

True
>>> sorted(a)==sorted(b)

Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: no ordering relation is defined for complex numbers

In Python 3 there are even more incomparable objects pairs.
--
Piet van Oostrum <>
URL: http://pietvanoostrum.com [PGP 8DAE142BE17999C4]
Private email:

Piet van Oostrum, Apr 24, 2009
4. ### Steven D'ApranoGuest

On Thu, 23 Apr 2009 21:51:42 -0400, Esmail wrote:

>> set(a) == set(b) # test if a and b have the same elements
>>
>> # check that each list has the same number of each element # i.e.
>> [1,2,1,2] == [1,1,2,2], but [1,2,2,2] != [1,1,1,2] for elem in set(a):
>> a.count(elem) == b.count(elem)

>
> Ah .. this part would take care of different number of duplicates in the
> lists. Cool.

At significant cost of extra work.

Counting the number of times a single element occurs in the list is O(N).
Counting the number of times every element occurs in the list is O(N**2).
Sorting is O(N*log N), so for large lists, sorting will probably be much
cheaper.

--
Steven

Steven D'Aprano, Apr 24, 2009
5. ### EsmailGuest

Piet van Oostrum wrote:
>>>>>> John Yeung <> (JY) wrote:

>
>> JY> It takes care of the duplicates, but so does your initial solution,
>> JY> which I like best:

>
>>>> sorted(a)==sorted(b)

>
>> JY> This is concise, clear, and in my opinion, the most Pythonic. It may
>> JY> well even be the fastest. (If you didn't have to match up the numbers
>> JY> of duplicates, the set solution would be most Pythonic and probably
>> JY> fastest.)

>
> But it may fail if the list cannot be sorted because it contains
> incomparable elements:

Ah .. good point .. something I had not considered. Lucky for me in
this case it's not an issue, but something I'll keep in mind for the
future.

Esmail, Apr 24, 2009
6. ### EsmailGuest

John Yeung wrote:
> so does your initial solution,
> which I like best:
>
>> sorted(a)==sorted(b)

>
> This is concise, clear, and in my opinion, the most Pythonic. It may
> well even be the fastest.

Great .. I can live with that

Esmail, Apr 24, 2009
7. ### Terry ReedyGuest

Steven D'Aprano wrote:
> On Thu, 23 Apr 2009 21:51:42 -0400, Esmail wrote:
>
>>> set(a) == set(b) # test if a and b have the same elements
>>>
>>> # check that each list has the same number of each element # i.e.
>>> [1,2,1,2] == [1,1,2,2], but [1,2,2,2] != [1,1,1,2] for elem in set(a):
>>> a.count(elem) == b.count(elem)

>> Ah .. this part would take care of different number of duplicates in the
>> lists. Cool.

>
> At significant cost of extra work.
>
> Counting the number of times a single element occurs in the list is O(N).
> Counting the number of times every element occurs in the list is O(N**2).

A frequency dict should be O(n) also, and hence faster than sorting.

> Sorting is O(N*log N), so for large lists, sorting will probably be much
> cheaper.
>
>

Terry Reedy, Apr 24, 2009