Próbuję oceniać ((x == a and y == b) or (x == b and y == a))
w Pythonie, ale wydaje się to trochę gadatliwe. Czy istnieje bardziej elegancki sposób?
python
boolean-logic
LetEpsilonBeLessThanZero
źródło
źródło
x,y, a,b
: czy są to ints / float / strings, dowolne obiekty, czy co? Gdyby były wbudowane typy i udało się zachować zarównox,y
ia,b
posortowanych, wtedy można uniknąć drugiego oddziału. Zauważ, że utworzenie zestawu spowoduje, że każdy z czterech elementówx,y, a,b
zostanie zaszyfrowany, co może, ale nie musi, być trywialne lub mieć wpływ na wydajność w zależności od tego, jakiego rodzaju są obiektami.((x == a and y == b) or (x == b and y == a))
może to wyglądać dziwacznie, ale 1) jego intencja jest krystalicznie czysta i zrozumiała dla wszystkich programistów nie-Pythona, a nie kryptycznych 2) interpretery / kompilatory zawsze dobrze sobie z tym poradzą i zasadniczo nie może skutkować niewykonalnym kodem, w przeciwieństwie do alternatywy Tak więc „bardziej elegancki” może mieć również poważne wady.Odpowiedzi:
Jeśli elementy są haszowalne, możesz użyć zestawów:
źródło
{1, 1, 2} == {1, 2, 2}
. W tym momencie potrzebujeszsorted
lubCounter
.Myślę, że najlepsze, co możesz dostać, to spakować je w krotki:
A może zawiń to w zestaw wyszukiwania
Właśnie dlatego, że zostało to wspomniane w kilku komentarzach, zrobiłem pewne czasy, a krotki i zestawy wydają się działać tutaj identycznie, gdy wyszukiwanie nie powiedzie się:
Chociaż krotki są w rzeczywistości szybsze, gdy wyszukiwanie się powiedzie:
Zdecydowałem się użyć zestawu, ponieważ przeprowadzam wyszukiwanie członkostwa, a koncepcyjnie zestaw lepiej pasuje do tego przypadku użycia niż krotka. Jeśli zmierzyłeś znaczącą różnicę między dwiema strukturami w konkretnym przypadku użycia, przejdź do szybszej. Nie sądzę jednak, żeby wydajność była tutaj czynnikiem.
źródło
if (a, b) in ((x, y), (y, x))
?set
rozwiązanie w odpowiedzi na rozwiązanie krotki z @Brilliand?Krotki sprawiają, że jest nieco bardziej czytelny:
To daje wskazówkę: sprawdzamy, czy sekwencja
x, y
jest równa sekwencji,a, b
ale ignorujemy kolejność. To tylko równość!źródło
,
tworzy krotkę, a nie listę. tak(x, y)
i(a, b)
to krotki, tak samo jakx, y
ia, b
.list
typu Python . Edytowane, ponieważ rzeczywiście było to mylące.Jeśli elementy nie są haszowalne, ale obsługują porównywanie zamówień, możesz spróbować:
źródło
complex
na przykład.Moim zdaniem byłby to najbardziej elegancki sposób
Jest to lepszy sposób niż używanie zbiorów, tj.
{a, b} == {y, x}
Jak wskazano w innych odpowiedziach, ponieważ nie musimy myśleć, czy zmienne są możliwe do skrócenia.źródło
Jeśli są to liczby, możesz użyć
(x+y)==(a+b) and (x*y)==(a*b)
.Jeśli są to porównywalne przedmioty, możesz użyć
min(x,y)==min(a,b) and max(x,y)==max(a,b)
.Ale
((x == a and y == b) or (x == b and y == a))
jest jasne, bezpieczne i bardziej ogólne.źródło
Jako uogólnienie na więcej niż dwie zmienne możemy użyć
itertools.permutations
. To jest zamiastmożemy pisać
I oczywiście dwie zmienne wersje:
źródło
O(N*N!)
; W przypadku 11 zmiennych może to zająć ponad sekundę. (Opublikowałem szybszą metodę, ale wciąż trwaO(N^2)
i zaczyna przejmować sekundę na 10k zmiennych; Wygląda więc na to, że można to zrobić szybko lub ogólnie (wrt. Hashability / orderability), ale nie oba: P)Możesz użyć krotek do przedstawienia swoich danych, a następnie sprawdzić włączenie zestawu, na przykład:
źródło
Masz już najbardziej czytelne rozwiązanie . Istnieją inne sposoby wyrażenia tego, być może przy użyciu mniejszej liczby znaków, ale są one mniej czytelne.
W zależności od tego, jakie wartości faktycznie reprezentują twój najlepszy zakład, należy zawrzeć czek w funkcji wypowiedzianą nazwą . Alternatywnie lub dodatkowo można modelować obiekty x, y i a, b w dedykowanych obiektach wyższej klasy, które następnie można porównać z logiką porównania w metodzie sprawdzania równości klas lub dedykowanej funkcji niestandardowej.
źródło
Wygląda na to, że OP zajmował się jedynie przypadkiem dwóch zmiennych, ale ponieważ StackOverflow jest również dla tych, którzy szukają tego samego pytania później, postaram się tutaj szczegółowo zająć przypadkiem ogólnym; Jedna poprzednia odpowiedź zawiera już ogólną odpowiedź
itertools.permutations()
, ale ta metoda prowadzi doO(N*N!)
porównań, ponieważ istniejąN!
permutacje zN
elementami. (To była główna motywacja tej odpowiedzi)Najpierw podsumujmy, w jaki sposób niektóre metody z poprzednich odpowiedzi odnoszą się do przypadku ogólnego, jako motywację do metody przedstawionej tutaj. Będę używać
A
do odwoływania się(x, y)
iB
do odniesienia(a, b)
, które mogą być krotkami o dowolnej (ale równej) długości.set(A) == set(B)
jest szybki, ale działa tylko wtedy, gdy wartości są haszowalne i możesz zagwarantować, że jedna z krotek nie zawiera żadnych zduplikowanych wartości. (Na przykład.{1, 1, 2} == {1, 2, 2}
, Jak wskazał @ user2357112 w odpowiedzi @Daniel Mesejo)Poprzednia metoda może zostać rozszerzona do pracy ze zduplikowanymi wartościami za pomocą słowników z licznikami zamiast zestawów: (To wciąż ma ograniczenie, że wszystkie wartości muszą być możliwe do skrótu, więc np. Zmienne wartości takie jak
list
nie będą działać)sorted(A) == sorted(B)
nie wymaga wartości mieszających, ale jest nieco wolniejszy i zamiast tego wymaga wartości uporządkowanych. (Więc np.complex
Nie będzie działać)A in itertools.permutations(B)
nie wymaga wartości skrótu ani zamówień, ale jak już wspomniano, maO(N*N!)
złożoność, więc nawet przy 11 elementach ukończenie może zająć sekundę.Czy istnieje sposób, aby być tak ogólnym, ale czy jest to znacznie szybsze? Dlaczego tak, „ręcznie” sprawdzając, czy jest taka sama ilość każdego elementu: (Złożoność tego jest
O(N^2)
taka, że nie jest to również dobre w przypadku dużych nakładów; na mojej maszynie 10 000 elementów może zająć sekundę - ale z mniejsze nakłady, takie jak 10 pozycji, jest tak samo szybki jak inne)Aby uzyskać najlepszą wydajność, można
dict
najpierw wypróbować metodę opartą na bazie , powrócić dosorted
metody opartej na bazie, jeśli to się nie powiedzie z powodu nieusuwalnych wartości, a na koniec wrócić docount
metody opartej na podstawie , jeśli to też się nie powiedzie z powodu nieuporządkowanych wartości.źródło