Множественный порядок присваивания и оценки в Python - PullRequest
44 голосов
/ 04 января 2012

Чем отличаются следующие выражения Python:

# First:

x,y = y,x+y

# Second:

x = y
y = x+y

Первый дает результаты, отличные от Второй .

например,

Первый:

>>> x = 1
>>> y = 2
>>> x,y = y,x+y
>>> x
2
>>> y
3

Второй:

>>> x = 1
>>> y = 2
>>> x = y
>>> y = x+y
>>> x
2
>>> y
4

y - 3 дюйма Первый и 4 дюйма Второй

Ответы [ 8 ]

69 голосов
/ 04 января 2012

В операторе присваивания правая часть всегда полностью оценивается до , когда выполняется фактическая установка переменных.Итак,

x, y = y, x + y

оценивает y (назовем результат ham), оценивает x + y (назовем spam), затем устанавливает x в ham и y до spam.То есть, это как

ham = y
spam = x + y
x = ham
y = spam

В отличие от

x = y
y = x + y

устанавливает x на y, затем устанавливает y на x (что == y) плюсy, так что это эквивалентно

x = y
y = y + y
11 голосов
/ 04 января 2012

Это объясняется в документации в разделе, озаглавленном «Порядок оценки» :

... при оценке присваивания оценивается правая часть перед левой стороной.

4 голосов
/ 04 января 2012

Первое выражение:

  1. Создает временный кортеж со значением y,x+y
  2. Присваивается другому временному кортежу
  3. Извлечение кортежа в переменные x и y

Второе утверждение на самом деле является двумя выражениями без использования кортежа.

Сюрприз в том, что первое выражение на самом деле:

temp=x
x=y
y=temp+y

Вы можете узнать больше об использовании запятой в " Формы в скобках ".

1 голос
/ 04 января 2012

Первое задание типа кортежа:

x,y = y,x+y

Где x - первый элемент кортежа, а y - второй элемент, поэтому вы делаете:

x = y
y = x+y

Когда второй выполняет прямое задание:

x=y
x=x+y
1 голос
/ 04 января 2012

Во втором случае вы присваиваете x+y x

В первом случае второй результат (x+y) присваивается y

Этопочему вы получаете разные результаты.

После вашего редактирования

Это происходит потому, что в операторе

x,y = y,x+y

все переменные в правом членеоцениваются и затем сохраняются в левых членах.Итак, first продолжить с правым членом, а second с левым членом.

Во втором утверждении

x = y
y = x + y

yo впервые оценено y и присвойте его x;таким образом, сумма x+y эквивалентна сумме y+y, а не x+x, что является первым случаем.

0 голосов
/ 13 февраля 2018

Я недавно начал использовать Python, и эта "особенность" сбила меня с толку. Хотя дано много ответов, я все равно опубликую свое понимание.

Если я хочу поменять местами значения двух переменных, в JavaScipt я бы сделал следующее:

var a = 0;
var b = 1;

var temp = a;
a = b;
b = temp;

Мне понадобится третья переменная для временного хранения одного из значений. Очень простой обмен не будет работать, потому что обе переменные будут иметь одно и то же значение.

var a = 0;
var b = 1;

a = b; // b = 1 => a = 1
b = a; // a = 1 => b = 1

Представьте, что у вас есть два разных (красного и синего) ведра и две разные жидкости (вода и масло) в них соответственно. Теперь попробуйте поменять ведра / жидкости (вода в синем и масло в красном ведре). Вы не можете сделать это, если у вас нет дополнительного ведра.

Python решает эту проблему "более чистым" способом / решением: Назначение кортежей .

a = 0
b = 1

print(a, b) # 0 1

# temp = a
# a = b
# b = temp

a, b = b, a # values are swapped

print(a, b) # 1 0

Полагаю, таким образом Python автоматически создает переменные "temp", и нам не нужно о них беспокоиться.

0 голосов
/ 17 января 2018

Давайте возьмем разницу.

x, y = y, x + y Это x tuple xssignment, mexns (x, y) = (y, x + y), как (x, y) = (y, x)

Stxrt из x быстрый пример:

x, y = 0, 1
#equivxlent to
(x, y) = (0, 1)
#implement xs
x = 0
y = 1

Когда доходит до (x, y) = (y, x + y) ExFP, попробуйте x напрямую

x, y = 0, 1
x = y #x=y=1
y = x + y #y=1+1
#output
In [87]: x
Out[87]: 1
In [88]: y
Out[88]: 2

Тем не менее,

In [93]: x, y = y, x+y
In [94]: x
Out[94]: 3
In [95]: y
Out[95]: 5

Результат отличается от первой попытки.

Спасибо, потому что Python сначала оценивает правую руку x+y Так что это эквивалентно:

old_x = x
old_y = y
c = old_x + old_y
x = old_y
y = c

В итоге, x, y = y, x+y означает,
x обменивается, чтобы получить old_value y,
y обменивается для получения суммы старого значения x и старого значения y,

0 голосов
/ 19 сентября 2017
a, b = 0, 1
while b < 10:
print(b)
a, b = b, a+b

Выход

1
1
2
3
5
8

переменные a и b одновременно получают новые значения 0 и 1, одинаковые a, b = b, a + b, a и b назначаются одновременно.

...