W rubinach 2.4:
x = ["a"]
y = {}
x[0] = y[x[0]] = y.fetch(x[0], y.length)
puts y #=> {"a"=>0}
W python 3.5:
x = ["a"]
y = {}
x[0] = y[x[0]] = y.get(x[0], len(y))
print(y) #=> {0: 0}
Dlaczego to?
ETA:
y[x[0]] = x[0] = y.get(x[0], len(y))
wytwarza oczekiwane zachowanie (ku mojemu rozczarowaniu)
Odpowiedzi:
5 dla odpowiedzi № 1Ruby i Python są różnymi językami i dokonują różnych wyborów. W Pythonie zadania są sprawozdania i ocenia wiele celów przypisania z z lewej na prawą. Ruby dokonał innych wyborów; zadania są wyrażenia w rezultacie są oceniane w odwrotnej kolejności.
Tak więc w Ruby to się dzieje:
- Oceniać
y.fetch(x[0], y.length)
, produkuje0
(brakuje klucza,y
jest pusty). - Oceniać
y[x[0]] = 0
, więcy["a"] = 0
. To wyrażenie powoduje0
. - Oceniać
x[0] = 0
(0
będący wynikiemy[x[0]] = 0
wyrażenie przydziału).
Zauważ, że w Ruby, ponieważ przypisanie jest wyrażenie. Może być zagnieżdżony w innych wyrażeniach, a wynikiem przypisania jest wartość celu po przypisaniu.
W Pythonie dzieje się tak zamiast:
- Oceniać
y.get(x[0], len(y))
, produkuje0
(brakuje klucza,y
jest pusty). - Oceniać
x[0] = 0
. - Oceniać
y[x[0]] = 0
, więcy[0] = 0
.
Z Pythona dokumentacja deklaracji zlecenia:
Instrukcja przypisania ocenia wyrażenielista (pamiętaj, że może to być pojedyncze wyrażenie lub lista rozdzielana przecinkami, ta ostatnia daje krotkę) i przypisuje pojedynczy wynikowy obiekt do każdej listy docelowej, od lewej do prawej.
Wyrażone jest więc wyrażenie po prawej stronie pierwszy, a następnie przypisanie odbywa się do każdego celu od lewej do prawej.
Python celowo składał deklaracje, ponieważ różnica między:
if a = 42:
i
if a == 42:
jest tak cholernie trudny do zauważenia, a nawet jeśli zamierzony naprawdę zaszkodzi czytelności kodu. W Pythonie liczy się czytelność. Dużo.
Ogólnie rzecz biorąc, naprawdę chcesz uniknąć przypisywania do nazw, które są następnie używane w kolejnych zadaniach w tej samej instrukcji. Nie przypisuj do x[0]
a następnie użyć x[0]
ponownie w tym samym zadaniu, to jest po prostu bardzo mylące.