1

Why is this happening?

Version 1:

mylist= [1,2,3,4,5]
print mylist
for index, value in enumerate(mylist):
    value = 0
print mylist

Version 2:

mylist= [[1],[2],[3],[4],[5]]
print mylist
for index, value in enumerate(mylist):
    value[0] = 0
print mylist

Output 1:

[1, 2, 3, 4, 5]
[1, 2, 3, 4, 5]

Output 2:

[[1], [2], [3], [4], [5]]
[[0], [0], [0], [0], [0]]

I assumed that both versions would make a local variable and do not overwrite the list itself. I guess that is not the case in second version. I'm using python 2.7. Clearly, I can have another variable inside of for loop that makes another copy of the value. It just took me some time to figure this out and it was messing up my code functionality.

Solution:

value = list(value)
Barmaley
  • 1,232
  • 20
  • 27
  • 3
    [Drastically Improve Your Python: Understanding Python's Execution Model](http://www.jeffknupp.com/blog/2013/02/14/drastically-improve-your-python-understanding-pythons-execution-model/) –  Mar 17 '13 at 18:15

2 Answers2

4

You are not assigning to value in the second version, you are assigning to an index contained in the list referred to by value.

Python names are references to values, not memory locations. Some of those values are mutable, such as a list. A list contains references to other values, so value is a list and value[0] is a reference contained in the list.

To change the list in the first example, use the index from enumerate to alter that index in the list:

for index, value in enumerate(somelist):
    somelist[index] = 0

If you did not want the nested lists in your second example to change, you should make a copy of them instead:

for index, value in enumerate(somelist):
    value = value[:]  # full list slice, same as a copy.
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • So what would be the best way to create new local variable? I tried reassigning value inside second version for loop but it still changes values in the list – Barmaley Mar 17 '13 at 18:21
  • How do I need to address it if I dont want to change the list? I just want temporary local variable that stores value of the value (Sorry for the confusion) – Barmaley Mar 17 '13 at 18:26
  • 1
    @Barmaley Make a copy of the list? `value = list(value)` – Xymostech Mar 17 '13 at 18:34
  • @Xymostech I tried and I get TypeError: 'list' object is not callable – Barmaley Mar 17 '13 at 18:40
  • 3
    @Barmaley That is because you are using the name 'list' for your variable, but `list` is a reserved word in Python, the method name used to create a list. Change your variable name to something like `my_list = [[1],[2],[3],[4],[5]]` – Fiver Mar 17 '13 at 18:49
  • @Pathétique Of course, thank you so much Xymostech and Pathétique!!! – Barmaley Mar 17 '13 at 18:52
0

Here is another pythonic way to local copy a list:

mylist= [[1],[2],[3],[4],[5]]
print mylist
mylst = []
for index, value in enumerate(mylist):
    mylst += [[value[0]]]
print mylst
kiriloff
  • 25,609
  • 37
  • 148
  • 229