I'm still a bit new to Python, but, I feel really stupid right now 'cause I've just spent an hour trying to figure out why this for loop isn't doing what I want. I shouldn't be spending an hour on a for loop. Anyway, I'm trying to generate a list of dictionaries, and give them each a unique number, so I do this...
def initiate(n):
records = {'num':0,'blah':0,'doubleblah':0}
x = []
for i in range(n):
x.append(records)
x[i]['num'] = i
return x
x = initiate(4)
print(x)
I expect the function to return this --
[
{'num': 0, 'doubleblah': 0, 'blah': 0},
{'num': 1, 'doubleblah': 0, 'blah': 0},
{'num': 2, 'doubleblah': 0, 'blah': 0},
{'num': 3, 'doubleblah': 0, 'blah': 0}
]
But it actually returns this --
[
{'num': 3, 'doubleblah': 0, 'blah': 0},
{'num': 3, 'doubleblah': 0, 'blah': 0},
{'num': 3, 'doubleblah': 0, 'blah': 0},
{'num': 3, 'doubleblah': 0, 'blah': 0}
]
...when I add a few print statements into the function, I discover that it seems to be adding the number to every dictionary in the list, instead of just the current dictionary. I really don't see how the code would add to all the dict's, since I explicitly use x[i] = i
to add the number to the current dictionary only.
What's happening is that you're appending a reference to the same dictionary to the list each time.
print list(map(id, initiate(4)))
# [42283920, 42283920, 42283920, 42283920]
Your function is correctly written as:
def initiate(n):
return [ {'num': i, 'blah': 0, 'doubleblah': 0} for i in range(n) ]
This produces a new instance of a dictionary each time.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With