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]