/ / Python quirk quirk w / list przypisać indeks, przypisać indeks dict i dict.get - python, ruby, przypisanie zmiennej

Python assiration quirk w / index index assign, dict index assign i dict.get - python, ruby, variable-assignment

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 № 1

Ruby 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), produkuje 0 (brakuje klucza, y jest pusty).
  • Oceniać y[x[0]] = 0, więc y["a"] = 0. To wyrażenie powoduje 0.
  • Oceniać x[0] = 0 (0 będący wynikiem y[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)), produkuje 0 (brakuje klucza, y jest pusty).
  • Oceniać x[0] = 0.
  • Oceniać y[x[0]] = 0, więc y[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.