Python 在包含列表的iterable上迭代
我本以为会发生以下情况:Python 在包含列表的iterable上迭代,python,Python,我本以为会发生以下情况: a = [[1],[2],[3]] for i in a: i = "x" print(a) 给予: ["x","x","x"] 但是a实际上保持不变。为什么会这样?我本以为I只是一个指向数组的指针。什么是i?就循环的第一次迭代而言,它肯定不是[1]的副本 a = [[1],[2],[3]] for i in range(0, len(a)-1): a[i] = 'X' print(a) 这是因为您正在“挑选”数组中每个对象的副本,作为循环中称为i
a = [[1],[2],[3]]
for i in a:
i = "x"
print(a)
给予:
["x","x","x"]
但是a
实际上保持不变。为什么会这样?我本以为I
只是一个指向数组的指针。什么是i
?就循环的第一次迭代而言,它肯定不是[1]的副本
a = [[1],[2],[3]]
for i in range(0, len(a)-1):
a[i] = 'X'
print(a)
这是因为您正在“挑选”数组中每个对象的副本,作为循环中称为i
的独立项
a = [[1],[2],[3]]
for copiedItem in a:
copiedItem = 'x' # Replaces your copy that you just picked out from a.
这意味着您要替换项目的副本,而不是数组/列表中的实际项目。您需要通过索引a[]
来替换列表中的项目
另一个例子是:
a = ['moo', 'cow', 'cat']
myCopy = a[0] # Copies 'moo' into 'myCopy'
myCopy = 'THE DEVIL' # Replaces 'moo'.. over your copy..
print(a)
['moo', 'cow', 'cat']
print(myCopy)
'THE DEVIL'
可能是一个不好的例子,但它基本上做了相同的事情,只是for循环是list对象的一个迭代生成器,它以异步
return
的形式返回每个项,称为yield
。每个返回的项只是一个副本,而不是对初始对象的引用,因此与复制a[0]
:)从指针的角度考虑Python可能会产生误导。相反,您需要学会根据绑定到名称的对象来思考
所以
依次将名称i
绑定到iterable对象a
中的每个对象,在本例中,这些对象是单元素列表
然后
将文本字符串对象“x”
绑定到名称i
,该名称覆盖了以前的绑定,因此它对a
或其内容没有影响
注意
>>> for i in a:
... i[0] = "x"
...
>>> print a
[['x'], ['x'], ['x']]
做了您(可能)期望的事情,因为i[0]=“x”
正在修改当前绑定到i
的列表,所以它没有将新对象绑定到i
SO member Ned Batcheld是一本关于此主题的优秀指南。作为一种更具python风格的方式,您可以使用
枚举@Kasra是正确的,但是因为这是一个辅助函数,基本上也是这样。为了便于学习,我保持了它的整洁和简单。由于您通过索引访问列表中的项来替换列表中的项,并且enumerate为您提供了超出所需的数据(它同时提供索引和值),因此最好通过这种方式来了解索引的工作原理。但你的观点是正确的。恐怕你的假设是错误的,I
实际上是一个副本。见下面我的答案。
i = "x"
>>> for i in a:
... i[0] = "x"
...
>>> print a
[['x'], ['x'], ['x']]