Jakie jest znaczenie „(1,) == 1” w Pythonie?

119

Testuję strukturę krotki i stwierdziłem, że jest to dziwne, gdy używam ==operatora takiego:

>>>  (1,) == 1,
Out: (False,)

Kiedy przypiszę te dwa wyrażenia do zmiennej, wynik jest prawdziwy:

>>> a = (1,)
>>> b = 1,
>>> a==b
Out: True

Moim zdaniem to pytanie różni się od reguły składni końcowego przecinka krotki w Pythonie . Pytam o grupę wyrażeń między ==operatorem.

Pythoner
źródło
16
Patrząc na poprzednie pytanie OP zaledwie 2 godziny temu, wydaje się cudowne (lub dziwne), że samo sformułowanie pytania w inny sposób może prowadzić do różnych rezultatów (i akceptacji wśród społeczności).
AKS
24
@AKS To są różne
pytania
7
@AKS Chociaż pytania są tutaj nieznacznie inne, całkowicie zgadzam się z twoim punktem widzenia. Efekt stadny, czyli HNQ.
Szalony
5
@PythonNewHand Rzeczywiście, jest to całkowicie do przyjęcia. Dlatego dodałem to, stawiając pytanie inaczej .
AKS
3
@CiroSantilli 巴拿馬 文件 六四 事件 法轮功 How do you figure? Przejrzałem te odpowiedzi i nie widziałem nic, co zdawałoby się obejmować tę konkretną sytuację.
Dan Getz

Odpowiedzi:

88

Inne odpowiedzi już pokazały, że zachowanie to wynika z pierwszeństwa operatorów, jak opisano tutaj .

Pokażę ci, jak samodzielnie znaleźć odpowiedź, gdy następnym razem będziesz mieć podobne pytanie. Możesz zdekonstruować sposób analizy wyrażenia za pomocą astmodułu:

>>> import ast
>>> source_code = '(1,) == 1,'
>>> print(ast.dump(ast.parse(source_code), annotate_fields=False))
Module([Expr(Tuple([Compare(Tuple([Num(1)], Load()), [Eq()], [Num(1)])], Load()))])

Z tego widać, że kod jest analizowany, jak wyjaśnił Tim Peters :

Module([Expr(
    Tuple([
        Compare(
            Tuple([Num(1)], Load()), 
            [Eq()], 
            [Num(1)]
        )
    ], Load())
)])
wim
źródło
1
Innym przydatnym narzędziem jest dis- w tym przypadku zobaczysz dwa LOAD_CONSTz różnymi wartościami ( (1,)i 1) i BUILD_TUPLEkodem opp.
mgilson
153

To tylko pierwszeństwo operatorów. Twój pierwszy

(1,) == 1,

grupy takie jak ta:

((1,) == 1),

więc tworzy krotkę z pojedynczym elementem na podstawie wyniku porównania jednoelementowej krotki 1,z liczbą całkowitą 1dla równości Nie są równe, więc otrzymujesz 1-krotkę False,jako wynik.

Tim Peters
źródło
61
Niezupełnie, ale 1-krotki mają dziwną składnię. W ogóle, że będziemy znacznie bardziej zaskoczony, jeśli, na przykład, 1+2, 2==3, 4*7tak nie grupę jako (1+2), (2==3), (4*7). W praktyce 1-krotki są rzadko używane (no cóż, poza pytaniami StackOverflow ;-)).
Tim Peters
6
Być może „nieoczekiwany” byłby lepszym słowem niż „dziwny”. Czuję się trochę tak, jakbym patrzył na jeden z tych rysunków, które mogą być dwiema rzeczami, w zależności od twojej perspektywy i ostrości . Operator równości jest tak duży w porównaniu z przecinkami, że łatwo jest się na nim skupić i założyć, że wynikiem będzie True/ False. Teraz, gdy rozumiem, co się dzieje, jest to całkowicie oczywiste i rozsądne.
skrrgwasme
31
A teraz wiesz, co oznacza „Zen of Python”, mówiąc, że jedyny oczywisty sposób na zrobienie tego „może nie być oczywisty na początku, chyba że jesteś Holendrem” ;-)
Tim Peters
7
To trochę mylące, kiedy czytasz dokument i widzisz, że to, co tworzy krotkę, to przecinek, a nie nawiasy! Zatem w tym stwierdzeniu przecinek po prawej stronie nie jest traktowany jako część testu, ale jest traktowany jako separator! Nieoczekiwane zachowanie!
Ikra_5
3
Powszechna rada dotycząca wyrażeń brzmi: „w razie wątpliwości użyj nawiasów”. Następnie dobrze jest umieścić nawiasy wokół wszystkich krotek jednokrotnych, nawet jeśli nie są one częścią składni krotki.
nigel222
12

Kiedy to zrobisz

>>> (1,) == 1,

tworzy krotkę z wynikiem porównania krotki (1,) z liczbą całkowitą, a tym samym zwraca False.

Zamiast tego, gdy przypisujesz zmienne, porównywane są ze sobą dwie równe krotki .

Możesz spróbować:

>>> x = 1,
>>> x
(1,)
mng
źródło