Семантика одновременного присваивания в Python
Рассмотрим следующий код Python 3:
a = [-1,-1,-1]
i = 0
А теперь рассмотрим следующие две версии одновременного присваивания как a, так и i:
Версия задания 1:
a[i],i = i,i+1
Версия задания 2:
i,a[i] = i+1,i
Я ожидаю, что эти две версии одновременных назначений будут семантически эквивалентными. Однако, если вы проверяете значения a и i после каждого из одновременных назначений, вы получаете разные состояния:
Выход для print(a,i)
после назначения версии 1:
[0, -1, -1] 1
Выход для print(a,i)
после назначения версии 2:
[-1, 0, -1] 1
Я не эксперт по семантике Python, но такое поведение кажется странным. Я ожидаю, что оба назначения будут вести себя как версия назначения 1. Более того, если вы проверите следующую ссылку, можно ожидать, что обе версии назначения приведут к одному и тому же состоянию:
Ссылка на отрывок из книги в Google Книгах
Что-то мне не хватает в семантике Python для одновременных назначений?
Примечание: это странное поведение, похоже, не воспроизводимо, например, когда переменная a
имеет целочисленный тип; кажется требует a
быть списком типов (может быть, это так для любого изменяемого типа?).
1 ответ
В этом случае:
i, a[i] = i + 1, i
Правая часть соответствует кортежу (1, 0). Этот кортеж затем распаковывается в i
а потом a[i]
, a[i]
оценивается во время распаковки, а не до, поэтому соответствует a[1]
,
Так как правая сторона оценивается до того, как произойдет распаковка, ссылаясь на a[i]
на правой стороне всегда будет a[0]
независимо от конечного значения i
Вот еще один бесполезный забавный пример для вас, чтобы удаться
>>> a = [0,0,0,0]
>>> i, a[i], i, a[i] = range(4)
>>> a
[1, 0, 3, 0]