Jack_of_All_Trades
Jack_of_All_Trades

Reputation: 11498

Using list comprehension to compare elements of two arrays

How can I use list comprehension in python to compare if two arrays has same elements or not?

I did the following:

>>> 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]

I also want to output the False if not true rather than outputting just two trues like in the latter case but don't know how to do it.

Finally, I want to get one True/False value (if all are true then true, if one of them is false, then false) rather than the list of true and/or false. I know the simple loop to iterate over pp(list of true and false) is enough for that but I am sure there is more pythonic way to that.

Upvotes: 1

Views: 1979

Answers (3)

Steven Rumbalski
Steven Rumbalski

Reputation: 45552

set(aa) == set(bb)

This has the same effect but may be slightly faster

not set(aa).symmetric_difference(bb)

If you need [1,1] to be not equivalent to [1] do

sorted(aa) == sorted(bb)

Upvotes: 2

Martijn Pieters
Martijn Pieters

Reputation: 1124100

You are testing every element of each list against every element of the other list, finding all combinations that are True. Apart from inefficient, this is also the incorrect approach.

Use membership testing instead, and see all these tests are True with the all() function:

all(el in bb for el in aa)

all() returns True if each element of the iterable you give it is True, False otherwise.

This won't quite test if the lists are equivalent; you need to test for the length as well:

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

To make this a little more efficient for longer bb lists; create a set() from that list first:

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)

This still doesn't deal with duplicate numbers very well; [1, 1, 2] is equivalent to [1, 2, 2] with this approach. You underspecified what should happen in such cornercases; the only strict equivalent test would be to sort both inputs:

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

where we first test for length to avoid having to sort in case the lengths differ.

If duplicates are allowed, whatever the length of the input, you can forgo loops altogether and just use sets:

not set(aa).symmetric_difference(bb)

to test if they have the same unique elements.

Upvotes: 7

Zhubarb
Zhubarb

Reputation: 11905

"You are testing every element of each list against every element of the other list, finding all combinations that are True. Apart from inefficient, this is also the incorrect approach."

I agree with the above statement, the below code lists the False values as well but I don't think you really need this.

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

>>> False in bp
True

Upvotes: 1

Related Questions