Austin Dalton
Austin Dalton

Reputation: 3

Updating Nested Dictionary with for loop python

I am trying to update a nested dictionary within a for loop, but the final output seems to over writing the previous key values.

a = {}
b = {}
f=0
for x in range(3):
    a['test1'] = 1+f
    a['test2'] = 2+f
    a['test3'] = 3+f
    f = f+1
    b[f] = a

print(b)

Output:

{1: {'test1': 3, 'test2': 4, 'test3': 5}, 2: {'test1': 3, 'test2': 4, 'test3': 5}, 3: {'test1': 3, 'test2': 4, 'test3': 5}}

Expected Output:

{1: {'test1': 1, 'test2': 2, 'test3': 3}, 2: {'test1': 2, 'test2': 3, 'test3': 4}, 3: {'test1': 3, 'test2': 4, 'test3': 5}}

Upvotes: 0

Views: 592

Answers (4)

hxalchemy
hxalchemy

Reputation: 374

Here is a possible solution

b = {}
f=0
for x in range(3):
#add the part below

    a = {}

################

    a['test1'] = 1+f
    a['test2'] = 2+f
    a['test3'] = 3+f
    f = f+1
    b[f] = a



print(b)

Including "a" outside the loop was updating its values on each iteration, resetting the value of an allows you to execute your code accordingly.

Upvotes: 0

jtorca
jtorca

Reputation: 1541

When you do b[f]=a you assign item f of dictionary b to dictionary a, so if you change the values of dictionary a then all elements of b will point to this modified a. Instead, try creating a new dictionary and updating the values of b:

b = {}
f=0
for x in range(3):
    a = {}
    a['test1'] = 1+f
    a['test2'] = 2+f
    a['test3'] = 3+f
    f = f+1
    b[f] = a

print(b)
{1: {'test1': 1, 'test2': 2, 'test3': 3}, 2: {'test1': 2, 'test2': 3, 'test3': 4}, 3: {'test1': 3, 'test2': 4, 'test3': 5}}

Or you can try this one liner:

b = {f:{'test{}'.format(i):i+f for i in range(1,4)} for f in range(1,4)}
print(b)
{1: {'test1': 2, 'test2': 3, 'test3': 4}, 2: {'test1': 3, 'test2': 4, 'test3': 5}, 3: {'test1': 4, 'test2': 5, 'test3': 6}}

Upvotes: 0

jpf
jpf

Reputation: 1475

Dictionaries are mutable, so when a dictionary is assigned to another variable, a pointer is simply assigned rather than a copy of the original dictionary. If you change the original dictionary, you change any variables associated with the pointer to that dictionary. To avoid this, you simply need b[f]=a.copy() instead of b[f]=a. This is for a single level dictionary; for deeper levels you should use copy.deepcopy.

Upvotes: 0

olenscki
olenscki

Reputation: 507

I think this will do

a = {}
b = {}

for f in range(3):
    a['test1'] = 1+f
    a['test2'] = 2+f
    a['test3'] = 3+f
    b[f] = a

Upvotes: 1

Related Questions