Python:list在for循环之后不会发生变化
该列表是否应该变异为Python:list在for循环之后不会发生变化,python,Python,该列表是否应该变异为[2,3]?结果显示为[1,2]。 为什么?不,为什么要这样做 条目只是一个名称,for循环将其分配给列表中的每个整数。如果随后将该名称重新指定为指向不同的整数,则列表不会在意。要修改原始列表,可以执行以下操作: a =[1,2] for entry in a: entry = entry + 1 print a 或者您可以将for循环更改为“一行”,如下所示: a =[1,2] for x in range(len(a)): a[x] = a[x] +
[2,3]
?结果显示为[1,2]
。
为什么?不,为什么要这样做
条目
只是一个名称,for循环将其分配给列表中的每个整数。如果随后将该名称重新指定为指向不同的整数,则列表不会在意。要修改原始列表,可以执行以下操作:
a =[1,2]
for entry in a:
entry = entry + 1
print a
或者您可以将for循环更改为“一行”,如下所示:
a =[1,2]
for x in range(len(a)):
a[x] = a[x] + 1
print a
任一方法的输出:
a =[1,2]
a = [x + 1 for x in a]
print a
两种方法的不同之处在于,第一种方法修改列表,而第二种方法创建新列表。否,因为当您执行
entry=entry+1
操作时,您创建了一个新的整数对象并将其绑定到名称entry
,绑定到该名称的原始对象不受影响
请记住,在Python中,整数对象是不可变的。但是,如果a
包含可变对象,如列表,则可以执行以下操作:
[2, 3]
然后a
中的项目将发生变异:
输出
a = [[1], [2]]
for entry in a:
entry += [1]
print a
请注意,如果您刚刚执行了entry=entry+[1]
,那么a
将保持不变,因为简单赋值将新对象绑定到名称
您可能会发现这篇文章很有帮助:,它是由经验丰富的Ned Batchelder编写的。Python中的所有变量都包含指向存储在某处的某个对象的引用(即指针)。偶数整数是对象。赋值将指针更改为指向另一个对象,它不会修改所指向的项 当您这样做时:
[[1, 1], [2, 1]]
第一次通过循环时,条目将指向整数1
,因为a
(称为a[0]
)的第一个元素指向整数
现在,整数1
不存储在列表中,并且条目
不是指向列表中某个插槽的指针。相反,entry
和a[0]
指向同一个对象,即整数1
当您执行entry=entry+1
(或仅执行entry+=1
)时,entry
将更改为指向整数2
。但是,a[0]
不会更改,因为您没有更改它。它仍然指向整数1
迭代列表时修改列表的python方法是使用enumerate()
。这将为您提供索引(您需要修改列表项)和列表中的值
a = [1, 2]
for entry in a:
entry = entry + 1
在这里,您实际上并没有使用现有的元素值,因此您也可以使用range
:
for index, entry in enumerate(a):
a[index] += 1
另一种方法是使用切片赋值和生成器表达式。这将替换列表的全部内容:
for index in range(len(a)):
a[index] += 1
这样做的好处是,如果列表a
也有其他名称,则更改后的列表通过这些其他名称可见。如果这不是您想要的,您也可以这样做:
a[:] = (entry + 1 for entry in a)
这将使用更新的值创建一个新列表,并使a
指向该列表。a
中条目的可能重复创建列表中每个项目的副本并将其呈现给您。如果“在循环中”修改它,则影响的是副本而不是原始列表对象。在使用循环和其他东西时请记住这一点。@albert该问题中的任何答案都不会改变列表,而是返回一个新列表。@Torxed:No,
中的条目不会创建每个项目的副本;它将名称条目
依次绑定到a
中的每个项目。演示见我的答案。@Torxed:如果你小心的话,你可以通过条目
来处理原始对象,正如我的代码所示。你可以通过使用id
函数来证明它不是一个副本。它不会改变列表,而是创建一个新的列表并将其分配给原始变量。@Barmar我在这里冒险,假设OP被用于另一种语言,或者听说/被告知要改变一个整数列表,而这正是OP想要的,但实际上,它是一个来自其他语言的技术术语,不适用于#PM2Ring所描述的Python,但如果你在字里行间阅读它,如果你“创建一个新的列表,并将其原始值分配给它以代替变量”。请注意,你可以进行列表比较,并且仍然保留原始的列表对象,如果您真的想通过执行a[:]=[x+1 for x in a]
来实现此目的,我将指出,用户可能希望保持列表的原始结构,而不是像您指出的那样使用列表中的列表来实现它。无论如何,这是一堂关于Python对象的好课,以及为什么事情会以这种方式工作。@Torxed:当然,当你并不真正需要嵌套列表时,使用嵌套列表是愚蠢的。其他答案显示了修改列表内容的合理方法。我的示例的全部目的是显示,即使entry
引用了原始列表项,分配过程也会将新对象绑定到entry
。请看一看内德·巴奇尔德的优秀文章,我想你会发现它很有启发性。观点清楚,很好,因此代表我投赞成票是当之无愧的。我希望这是一个友好的讨论,因为我(再次)不是一个学者,并且有一段用逻辑类比而不是正确的术语挑起麻烦的历史。我会投赞成票,希望你继续努力!
a = [entry + 1 for entry in a]