Семантика одновременного присваивания в 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]
Другие вопросы по тегам