Reputation: 11
This is stumping me. This is a very simplified version of my code but exhibiting the exact issue:
test={"number":"0"}
testarray=[test]
print(testarray)
for x in range(5):
test["number"] = x
print(test)
testarray.append(test)
print("TestArray")
for x in testarray:
print(x)
The output is:
[{'number': '0'}]
{'number': 0}
{'number': 1}
{'number': 2}
{'number': 3}
{'number': 4}
TestArray
{'number': 4}
{'number': 4}
{'number': 4}
{'number': 4}
{'number': 4}
{'number': 4}
Why are all the entries set to the last value of the dictionary? I've also tried testarray.insert(len(testarray),test)
with the same result.
Upvotes: 1
Views: 94
Reputation: 6633
test={"number":"0"}
This line creates a new dictionary object with a key "number"
associated to the value "0"
. It also creates a name test
in the local scope, and associates that name with the dictionary object.
Later on in your code you have this line
test["number"] = x
Which will take the object referenced by the name test
(in this case the dictionary created on the previous line), update the value associated to the key "number"
within that object to refer to the same object x
refers to (in this case the numbers 0, 1, 2, 3, and then 4).
testarray.append(test)
This line adds a reference to that dictionary to the end of the array referenced by the name testarray
. Since it's adding a reference to the same dictionary each time, any changes to that dictionary will be reflected across all references.
To see a simple example of the same bug try this code:
foo = {'x': 0}
bar = [foo, foo, foo]
foo['x'] = 1
print(bar)
To fix your code I'd suggest:
testarray = []
for x in range(5):
testarray.append({"number": x})
Or the more idiomatic
testarray = [ {"number": x} for x in range(5) ]
Upvotes: 0
Reputation: 31
I think you put in the same dict multiple times in the list. You change the number every time in the same dict and the list stores the reference to the dict.
testarray = []
for i in range(5):
test = {"number": i}
testarry.append(test)
Upvotes: 3