Reputation: 95
I would like to generate a list of dicts by two layer loop. At the outer loop, the generated dict will be appended into the list. But the output is not expected as below:
inf = []
infdic = {}
keys = ['t1', 't2', 't3', 't4', 't5']
for c1 in range(2):
for c2 in range(5):
value = c1*10+c2
key = keys[c2]
infdic[key] = value
inf.append(infdic)
print c1, inf
The result of above code is:
0 [{'t4': 3, 't5': 4, 't2': 1, 't3': 2, 't1': 0}]
1 [{'t4': 13, 't5': 14, 't2': 11, 't3': 12, 't1': 10}, {'t4': 13, 't5': 14, 't2': 11, 't3': 12, 't1': 10}]
But what I want should be:
0 [{'t4': 3, 't5': 4, 't2': 1, 't3': 2, 't1': 0}]
1 [{'t4': 3, 't5': 4, 't2': 1, 't3': 2, 't1': 0}, {'t4': 13, 't5': 14, 't2': 11, 't3': 12, 't1': 10}]
It looks like the list inf
is pointed to infdic
, and it always changes as it does.
I am a little confused about how could this happen and how to fix it.
Upvotes: 0
Views: 108
Reputation: 2930
The problem is that you're not resetting infdic
in your outermost loop.
You loop through c1
and you set up infdic
as expected. But then you loop through c2
and overwrite the contents of infidc! It can be fixed by setting infdic = {}
in your outermost loop:
inf = [] keys = ['t1', 't2', 't3', 't4', 't5'] for c1 in range(2): infdic = {} for c2 in range(5): value = c1*10+c2 key = keys[c2] infdic[key] = value inf.append(infdic) print c1, inf
Also, regarding your observation:
It looks list "inf" is pointed to "infdic", and it always changes as it does.
Yes, that's right. When you write inf.append(infdic)
you are appending a pointer to infdic
to the list inf
. You're not copying a static version of the list (though you could using copy.deepcopy
). I suggest you read up on how Python uses pointers, and shallow/deep copying.
Upvotes: 1
Reputation: 881575
It looks list "inf" is pointed to "infdic", and it always changes as it does.
Yep, that's exactly what your code says to do, and, lo and behold, Python does precisely what you tell it to!-)
Fix: make a new infdic
each time around:
for c1 in range(2):
infdic = {}
for c2 in range(5):
...
Upvotes: 2