1

If I have a list of numbers, and I want to increment them using a for loop, why isn't this working:

>>> list=[1,2,3,4,5]
>>> for num in list: 
...  num=num+1
... 
>>> list
[1, 2, 3, 4, 5]

I expected to get [2,3,4,5,6].

I know I can get around this by doing

>>> newlist=[] 
>>> for num in list: 
...  newlist.append(num+1)
... 
>>> newlist
[2, 3, 4, 5, 6]
>>> 

but there must be an easier way.

4

3 回答 3

4

This is because you only get a reference to the variable in the list. When you replace it, you simply change what that reference is pointing to, so the item in the list is left unchanged. The best explanation for this is to follow it visually - step through the execution visualization found at that link and it should be very clear.

Note that mutable objects can be mutated in place, and that will affect the list (as the objects themselves will have changed, not just what the name you are working with is pointing to). For comparison, see the visualization here.

The best option here is a list comprehension.

new_list = [num + 1 for num in old_list]
于 2013-02-13T05:29:20.763 回答
4

This is an artifact of how assignment works in python. When you do an assignment:

name = something

You are taking the object something (which is the result of evaluating the right hand side) and binding it to the name name in the local namespace. When you do your for loop, you grab a reference to an element in the loop and then you construct a new object by adding 1 to the old object. You then assign that new object to the name num in your current namespace (over and over again).

If the objects in our original list are mutable, you can mutate the objects in a for loop:

lst = [[],[],[]]
for sublst in lst:
    sublst.append(0)

And you will see those changes in the original list -- Notice however that we didn't do any assignment here.

Of course, as suggested by lattyware, you can use a list-comprehension to construct a new list:

new_list = [x+1 for x in old_list]

and you can even make the assignment happen in place:

old_list[:] = [x+1 for x in old_list]
于 2013-02-13T05:29:56.213 回答
1

您可以通过索引数组来实现这一点。

>>> list=[1,2,3,4,5]
>>> for i in range(len(list)): 
...  list[i]=list[i]+1

这将绕过 Lattyware 提到的引用问题。

于 2013-02-13T05:31:39.520 回答