когда итерация списка python является и не является ссылкой

Может ли кто-нибудь предложить краткое объяснение различий между этими двумя операциями Python с точки зрения изменения списка?

demo = ["a", "b", "c"] for d in demo: d = "" print demo #output: ['a', 'b', 'c'] for c in range(len(demo)): demo[c] = "" print demo #output: ['', '', ''] 

Другими словами, почему первая итерация не изменяет список? Благодаря!

3 Solutions collect form web for “когда итерация списка python является и не является ссылкой”

Переменная цикла d всегда является ссылкой на элемент итерируемого объекта. Вопрос не в том, когда и когда это не ссылка. Речь идет о операции присваивания, которую вы выполняете с циклом.

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

Во втором примере вы выполняете операцию индексирования и назначаете новую ссылку на значение в этом индексе. demo остается той же ссылкой, и вы заменяете значение в контейнере.
Назначение действительно эквивалентно: demo.__setitem__(c, "")

 a = 'foo' id(a) # 4313267976 a = 'bar' id(a) # 4313268016 l = ['foo'] id(l) # 4328132552 l[0] = 'bar' id(l) # 4328132552 

Обратите внимание, как в первом примере изменился идентификатор объекта. Это ссылка на новый объект. Во втором мы индексируем в список и заменяем значение в контейнере, но список остается одним и тем же объектом.

В первом примере переменную d можно рассматривать как копию элементов внутри списка. Когда вы делаете d = "" , вы по существу модифицируете копию того, что находится внутри списка, что, естественно, не изменит список.

Во втором примере, делая range(len(demo)) и индексируя элементы внутри списка, вы можете напрямую получать и изменять элементы внутри списка. Таким образом, demo[c] изменит список.

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

Так:

 >>> demo = ["a", "b", "c"] >>> test = ["" for item in demo] >>> print test ["", "", ""] >>> demo2 = [1, 5, 2, 4] >>> test = [item for item in demo if item > 3] >>> print test [5, 4] 

Когда вы делаете d = <something> вы делаете переменную d ссылкой <something> . Таким образом, вы можете использовать d как если бы это было <something> . Однако, если вы выполняете d = <something else> , d теперь указывает на <something else> и больше не <something> (знак = используется как оператор присваивания). В случае demo[c] = <something else> вы присваиваете <something else> (c+1)th элемент в списке.

Однако следует отметить, что если элемент d имеет методы самомодификации, которые вы хотите вызвать, вы можете сделать

 for d in demo: d.<some method>() 

так как demo список содержит те объекты (или ссылки на объекты, которые я не помню), и, таким образом, если эти объекты будут изменены, список также будет изменен.

Python - лучший язык программирования в мире.