Is there a more elegant way to express ((x == a and y == b) or (x == b and y == a))? Is there a more elegant way to express ((x == a and y == b) or (x == b and y == a))? python python

Is there a more elegant way to express ((x == a and y == b) or (x == b and y == a))?


If the elements are hashable, you could use sets:

{a, b} == {y, x}


I think the best you could get is to package them into tuples:

if (a, b) == (x, y) or (a, b) == (y, x)

Or, maybe wrap that in a set lookup

if (a, b) in {(x, y), (y, x)}

Just since it was mentioned by a couple comments, I did some timings, and tuples and sets appear to perform identically here when the lookup fails:

from timeit import timeitx = 1y = 2a = 3b = 4>>> timeit(lambda: (a, b) in {(x, y), (y, x)}, number=int(5e7))32.8357742>>> timeit(lambda: (a, b) in ((x, y), (y, x)), number=int(5e7))31.6169182

Although tuples are actually faster when the lookup succeeds:

x = 1y = 2a = 1b = 2>>> timeit(lambda: (a, b) in {(x, y), (y, x)}, number=int(5e7))35.6219458>>> timeit(lambda: (a, b) in ((x, y), (y, x)), number=int(5e7))27.753138700000008

I chose to use a set because I'm doing a membership lookup, and conceptually a set is a better fit for that use-case than a tuple. If you measured a significant different between the two structures in a particular use case, go with the faster one. I don't think performance is a factor here though.


Tuples make it slightly more readable:

(x, y) == (a, b) or (x, y) == (b, a)

This gives a clue: we're checking whether the sequence x, y is equal to the sequence a, b but ignoring ordering. That's just set equality!

{x, y} == {a, b}