Замена выражений в выражении (замена трех и более переменных) в Python - PullRequest
2 голосов
/ 02 апреля 2019

Я попытался назначить три выражения в Python, но я неожиданный результат.

Начнем с простых перестановок. Вы, вероятно, знаете результат этого задания:

A = [10, 11, 12]
p = 0
A[p + 1], A[p] = A[p], A[p + 1]    # <--
print(A)

Результат (как и ожидалось):

[11, 10, 12]

Теперь я хотел быть немного смелее, поэтому попробовал это задание:

A = [10, 11, 12]
p = 0
p, A[p + 1], A[p] = p + 1, A[p], A[p + 1]   # <--
print(A)

Я думал, что результат будет:

[10, 12, 11]

Однако, результат был:

[10, 11, 10]

Что неожиданно!

Я прочитал Документацию Python относительно назначений :

Хотя определение присваивания подразумевает, что перекрытия между левой и правой сторонами являются «одновременными» (например, a, b = b, перестановка двух переменных), перекрытия в наборе назначенных для переменные встречаются слева направо, что иногда приводит к путанице. Например, следующая программа печатает [0, 2]:

x = [0, 1]
i = 0
i, x[i] = 1, 2         # i is updated, then x[i] is updated
print(x)

Я не получил аналогичные результаты для свопа. Я не понимаю логику моего обмена. Что происходит?

1 Ответ

4 голосов
/ 02 апреля 2019

Вы можете видеть это как сокращение для последовательных назначений слева направо, используя временные переменные:

p, A[p + 1], A[p] = p + 1, A[p], A[p + 1]

эквивалентно

temp1  = p + 1  # 1
temp2  = A[p]   # 10  (A[0])
temp3  = A[p+1] # 11  (A[1])
p      = temp1   # p    = 1
A[p+1] = temp2   # A[2] = 10
A[p]   = temp3   # A[1] = 11

, поэтому A = [10,11,10]

Если вы поместите p в конец списка, вы, вероятно, приблизитесь к ожидаемому результату:

A[p + 1], A[p], p = A[p], A[p + 1], p + 1

A is now [11,10,12]
P is now 1

Другими словами, постинкремент возможен, но предварительно увеличенне будет работать в сценарии такого типа (где в исходных данных используется предварительно увеличенный индекс)

Вы можете сделать это вручную, рассчитав смещение в исходных данных, но это будет несколько противоречить-интуитивный:

p, A[p+1], A[p] = p+1, A[p+1], A[p+2]
...