Python:for循环后列表没有变异

时间:2016-03-08 17:28:44

标签: python

a =[1,2]
for entry in a:
    entry = entry + 1
print a  

列表是否应该变为[2,3]?结果显示为[1,2]。 为什么呢?

4 个答案:

答案 0 :(得分:6)

要修改原始列表,您可以执行以下操作:

a =[1,2]
for x in range(len(a)):
    a[x] = a[x] + 1

print a

或者您可以将for循环更改为“oneliner”,如下所示:

a =[1,2]
a = [x + 1 for x in a]
print a

两种方法的输出:

[2, 3]

方法之间的区别是第一个修改列表,而第二个创建一个新列表。

答案 1 :(得分:5)

不,因为当您entry = entry + 1创建新的整数对象并将其绑定到名称entry时,绑定到该名称的原始对象不受影响。

请记住,在Python中,整数对象是不可变的。但是,如果a包含可变对象(如列表),则可以执行以下操作:

a = [[1], [2]]
for entry in a:
    entry += [1]
print a  

然后a 中的项目将被突变:

<强>输出

[[1, 1], [2, 1]]

请注意,如果刚刚执行entry = entry + [1],则a将保持不变,因为简单赋值将新对象绑定到名称。

您可能会发现这篇文章很有用:Facts and myths about Python names and values,由SO资深人士Ned Batchelder撰写。

答案 2 :(得分:1)

不,为什么要这样?

entry只是一个名称,for循环分配给列表中的每个整数。如果您随后重新指定该名称以指向其他整数,则列表并不关心。

答案 3 :(得分:1)

Python中的所有变量都包含存储在某处的某个对象的引用(即指针)。甚至整数都是对象。赋值将指针更改为指向另一个对象,它不会修改指向的项目。

当你这样做时:

a = [1, 2]
for entry in a:
    entry = entry + 1

第一次循环时,entry会指向整数1,因为它是a的第一个元素(称为{{1} }})指向。

现在,整数a[0]未存储在列表本身中,而1 不是指向列表中插槽的指针。相反,entryentry指向同一个对象,整数a[0]

当您执行1(或仅entry = entry + 1)时,entry += 1会更改为指向整数entry。但是,2不会改变,因为您没有更改它。它仍然指向整数a[0]

在迭代时修改列表的Pythonic方法是使用1。这为您提供了索引(您需要修改列表项)列表中的值。

enumerate()

此处您实际上并未使用现有元素值,因此您也可以使用for index, entry in enumerate(a): a[index] += 1

range

另一种方法是使用切片分配和生成器表达式。此替换列表的全部内容:

for index in range(len(a)):
    a[index] += 1

这样做的好处是,如果列表 a[:] = (entry + 1 for entry in a) 也有其他名称,则通过其他名称可以看到更改后的列表。如果这不是你想要的,你也可以这样做:

a

这将创建一个包含更新值的新列表,并使 a = [entry + 1 for entry in a] 指向它。