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 timeit
x = 1
y = 2
a = 3
b = 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 = 1
y = 2
a = 1
b = 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}