这是有效的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]
首先,您不能重新分配循环变量-可以,但是,这不会更改您要遍历的列表。因此,设置foo = 0将不会更改列表,而只会更改局部变量foo(该变量恰好包含每次迭代开始时的迭代值)。
foo = 0
foo
接下来,小数字(例如0和)1内部保存在小整数对象的池中(这是CPython实现的细节,不必是这种情况!)这就是为什么在foo为其分配ID后,ID相同的原因0。id基本上0是池中该整数对象的id 。
0
1
如果要在遍历列表时更改列表,很不幸,您将不得不按索引访问元素。因此,如果要保持输出不变,但[0, 0, 0]最后要保留输出,则必须遍历索引:
[0, 0, 0]
for i in range(len(bar)): print id(bar[i]) bar[i] = 0 print id(bar[i]) print bar
否则,这实际上是不可能的,因为一旦将列表的元素存储在变量中,就会有一个单独的引用,该引用未链接到存储在列表中的元素。并且由于大多数这些对象都是不可变的,并且在为变量分配新值时创建了一个新对象,因此您将无法获取列表的引用进行更新。