Переменные получают разные значения при одних и тех же операциях

#python #python-3.x

#python #python-3.x

Вопрос:

Это основная проблема понимания.

Я попытался изменить порядок некоторого кода, и хотя операции предположительно эквивалентны, я получаю разные значения. Я начал с этой строки:

 q, r, m = 10*q, 10*(r-m*t), (10*(3*q r))//t - 10*m
  

и изменил его на:

 q*=10;  r=10*(r-m*t);   m= (10*(3*q r))//t - 10*m;
  

(С начальными значениями q = 1, r = 6, t = 3, m = 3).

Когда я запускаю только вторую строку, m получает значение -30 (что является точным, если я правильно следовал порядку операций), в то время как запуск первой выдает m = 0, что и требуется программой.

Чего мне здесь не хватает? Присваивает ли метод comma значение после выполнения всех других назначений?

Комментарии:

1. При использовании x, y = foo, bar синтаксиса все инструкции выполняются перед присвоением значений переменным. При использовании x=foo; y=bar это не так.

2. Итак, это было так просто.. Я думаю, что это лучше во всех отношениях для кода 😅

3. Обратите внимание, что вы можете безопасно извлечь q присваивание. Подробности смотрите в моем ответе

Ответ №1:

Назначения в q, r, m = 10*q, 10*(r-m*t), (10*(3*q r))//t - 10*m выполняются независимо путем вычисления правой части всех назначений, при этом никто не влияет на другие, что означает, что при (10*(3*q r))//t - 10*m вычислении используется старое значение q , а не новое 10*q (то же самое с r ). Обратите внимание, что единственная разница заключается в значении m , которое зависит от значений r и q , которые не меняются во время m присвоения.

Ответ №2:

Проблема в том, что ваш первый фрагмент кода оценивает каждое выражение справа, прежде чем присваивать результаты вашим q , r и m переменным. Ваш второй фрагмент вместо этого присваивает:

 q*=10
r=10*(r-m*t)
  

-перед оценкой:

 m= (10*(3*q r))//t - 10*m
  

что изменяет результат. Если вы должны использовать последний фрагмент, вам нужно будет ввести временную переменную для хранения исходных q и r значений переменных для использования в конечном выражении.

Фактически, поскольку q не зависит ни от одной из других переменных, вы могли бы фактически присвоить ее значение последней, сохранив два других в пути, чтобы немного упростить выражение:

 r, m = 10*(r-m*t), (10*(3*q r))//t - 10*m
q *= 10
  

Ответ №3:

В первом случае все присваивания используют значения переменных до выполнения каких-либо присваиваний.

Во втором случае вы меняете одни переменные раньше других (ваши последующие назначения используют новые значения переменных).

Сравните a, b = b, a с a = b; b = a . В первом случае значения поменяются местами, во втором — нет.