0

I am facing an issue that i cannot solve on my own right now. Its about the following snippet:

counter = 0
appendList = []
valueList = [[0], [0]]

for i in range(0,3):

    valueList[1] = counter
    print "Loop " , i  , " valueList: " , valueList
    print "Appending (valueList): " , valueList , " to (appendList): " , appendList
    appendList.append(valueList)
    counter = counter + 1


print "Final appendList: " , appendList

This results in the following output:

Loop  0  valueList:  [[0], 0]
Appending (valueList):  [[0], 0]  to (appendList):  []
Loop  1  valueList:  [[0], 1]
Appending (valueList):  [[0], 1]  to (appendList):  [[[0], 1]]
Loop  2  valueList:  [[0], 2]
Appending (valueList):  [[0], 2]  to (appendList):  [[[0], 2], [[0], 2]]
Final appendList:  [[[0], 2], [[0], 2], [[0], 2]]

I wanted the Snippet to add different List-Items to the appendList. The final result should have looked like this:

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

But as you can see, the snippet fills the appendList with the same values of the highest counter.

Can someone please explain this behavior to me or tell me, where my mistake is?

3
  • Assign a copy every time, like this appendList.append(valueList[:]) Commented Oct 11, 2015 at 16:06
  • Thanks mate, that solved my issue. Can you explain why? Commented Oct 11, 2015 at 16:10
  • Writing an answer on that right now. Commented Oct 11, 2015 at 16:11

6 Answers 6

2

valueList is the same object each time you append it, so modifying it in one place appears to modify it everywhere.

>>> a = [0]
>>> b = a
>>> a[0] = 42
>>> b
[42]

You need to append a copy of it in order to add a new list each time.

appendList.append(valueList[:])
Sign up to request clarification or add additional context in comments.

Comments

1

You can try:

counter = 0
appendList = []
valueList = [[0], [0]]

for i in range(0,3):

    valueList[1] = counter
    print "Loop " , i  , " valueList: " , valueList
    print "Appending (valueList): " , valueList , " to (appendList): " , appendList
    appendList.append(valueList[:])
    counter = counter + 1


print "Final appendList: " , appendList

Output:

Loop  0  valueList:  [[0], 0]
Appending (valueList):  [[0], 0]  to (appendList):  []
Loop  1  valueList:  [[0], 1]
Appending (valueList):  [[0], 1]  to (appendList):  [[[0], 0]]
Loop  2  valueList:  [[0], 2]
Appending (valueList):  [[0], 2]  to (appendList):  [[[0], 0], [[0], 1]]
Final appendList:  [[[0], 0], [[0], 1], [[0], 2]]

Explanation:

When you assign valuelist object, all elements are assign from referance object. So, instead b = a, you can do b = a [:] because it's only copy each time from this object.

>>> a = [1, 2, 3]
>>> b = a
>>> a[:] = [4, 5, 6]
>>> b
[4, 5, 6]
>>> a
[4, 5, 6]
>>> b = a [:]
>>> a = [1, 2, 3]
>>> b
[4, 5, 6]
>>> a
[1, 2, 3]
>>> 

3 Comments

Although it solves the problem, this doesn't explain why and is an exact copy of @thefourtheye's comment.
Okk just wait. I am writing explanation
@ppperry: Now it's okk?
0

appendList contains a reference to the current value of valueList, so when you modify valueList, the copies in appendList change. You need to create a copy of valueList each time you put in it appendList.

Comments

0
counter = 0
appendList = []
valueList = [[0], [0]]

print(valueList[1][0])

for i in range(0,3):

    print(counter)
    valueList[1][0] = counter # this was wrong
    print ("Loop " , i  , " valueList: " , valueList)
    print ("Appending (valueList): " , valueList , " to (appendList): " , appendList)
    appendList.append(valueList)
    valueList = [[0], [0]] # and this was absent
    counter += 1

print(appendList)

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

Comments

0

valueList still points to a single object. You can check this by printing out the id(valueList). id gives identity of the object. i.e. the memory address of the object. In your example, if you print the id, it will be always same.

counter = 0
appendList = []
valueList = [[0], [0]]

for i in range(0,3):
    print "id of valueList before", id(valueList)
    #creates a copy of valueList.
    valueList = valueList[:]
    print "id of valueList after", id(valueList)
    valueList[1] = counter
    print "Loop " , i  , " valueList: " , valueList
    print "Appending (valueList): " , valueList , " to (appendList): ", appendList
    appendList.append(valueList)
    counter = counter + 1


print "Final appendList: " , appendList

Comments

0

A good habit is also to check the efficiency of your code afterwards: you are defining multiple variables while (to me) you are interested in appendList.

appendList = [ [[0], x] for x in range(3) ] # doStuff for index in range of n print appendList With list comprehension you can reduce it to only the necessary computation.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.