python присваивает значения элементам списка в цикле

Является ли это действительным поведение python? Я думаю, что конечный результат должен быть [0,0,0], а функция id () должна возвращать одинаковые значения каждой итерации. Как сделать это pythonic, а не использовать перечисление или диапазон (len (bar))?

bar = [1,2,3] print bar for foo in bar: print id (foo) foo=0 print id(foo) print bar 

вывод:

 [1, 2, 3] 5169664 5169676 5169652 5169676 5169640 5169676 [1, 2, 3] 

4 Solutions collect form web for “python присваивает значения элементам списка в цикле”

Прежде всего, вы не можете переназначить переменную цикла – ну, вы можете, но это не изменит список, который вы повторяете. Поэтому установка foo = 0 не изменит список, а только локальную переменную foo (которая, как оказалось, содержит значение для итерации в начале каждой итерации).

Далее, небольшие числа, такие как 0 и 1 , внутренне хранятся в пуле небольших целых объектов (это деталь реализации CPython, это не обязательно!) Вот почему идентификатор для foo одинаковый после того, как вы назначили 0 к нему. Идентификатор – это в основном идентификатор этого целочисленного объекта 0 в пуле.

Если вы хотите изменить свой список во время итерации по нему, вам, к сожалению, придется обращаться к элементам по индексу. Поэтому, если вы хотите сохранить вывод таким же, но в конце [0, 0, 0] , вам придется перебирать индексы:

 for i in range(len(bar)): print id(bar[i]) bar[i] = 0 print id(bar[i]) print bar 

В противном случае это невозможно, поскольку, как только вы храните элемент списка в переменной, у вас есть отдельная ссылка на него, которая не привязана к той, которая хранится в списке. И поскольку большинство этих объектов неизменяемы и вы создаете новый объект при назначении нового значения переменной, вы не получите ссылку на список для обновления.

Да, вы получили обычное поведение Python. Присвоение нового значения foo изменит идентификатор foo и не изменит значения, сохраненные в bar .

Если вам нужен список нулей, вы можете сделать:

 bar = [0] * len(bar) 

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

 bar = [x * 2 for x in bar] 

Или вы можете использовать map :

 def double(x): return x * 2 bar = map(double, bar) 

вы на самом деле не изменили список вообще. первая вещь для цикла – это присвоить bar [0] foo (эквивалентно foo = bar [0]). foo – это просто ссылка на 1. Затем вы назначаете другой onject 0 в foo. Это изменило ссылку foo на 0. Но вы не изменили бар [0]. Помните, что foo как переменная, reference bar [0], но назначить другое значение / object для foo не влияет на bar [0] вообще.

 bar = [0 for x in bar] 

Длинный ответ: foo – это просто локальное имя, а переупорядочение не влияет на список. Переменные Python на самом деле являются просто ключами: парами значений, а не символическими именами для мест памяти.

  • Проверка того, принадлежит ли переменная классу в python
  • Python: как обращаться к имени экземпляра?
  • SQLAlchemy: изменение отдельного объекта
  • Когда использовать Singleton в python?
  • Синтаксис инициализатора объекта (c #) в python?
  • Как python обрабатывает экземпляр объекта в цикле 'for'
  • Как избежать нескольких экземпляров программы?
  • переменные экземпляра класса python и переменные класса
  • Python - лучший язык программирования в мире.