Когда вы выполняете s[a], s[b] = s[b], s[a]
, правая часть =
полностью оценивается перед назначением значений обратно в список, поэтому однострочные замены работают в Python. Однако, похоже, что левая часть =
- это не , вычисляемая сразу, а одна за другой. Таким образом, для s[0], s[s[0]] = s[s[0]], s[0]
s[0]
в s[s[0]]
слева оценивается после того, как s[0]
было присвоено новое значение.
Это можно проверить, заключив индексы в функцию, которая печатает перед их возвратом:
>>> s = [1, 2]
>>> f = lambda i, j: print("get", i, j) or j
>>> s[f("a",0)], s[f("b",s[f("c",0)])] = s[f("d", s[f("e", 0)])], s[f("f", 0)]
get e 0
get d 1
get f 0
get a 0
get c 0
get b 2 <-- updated to 2 before s[0] was evaluated
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: list assignment index out of range
Другими словами, выражение s[0], s[s[0]] = s[s[0]], s[0]
кажется примерно эквивалентным следующему, то есть индексы , используемые в LHS, вообще не оцениваются один раз перед присвоением новых значений:
tmp = (s[s[0]], s[0])
s[0] = tmp[0]
s[s[0]] = tmp[1]