1

I was really stumped to find that creating a list of dictionaries from a loop does not yield the expected results unless the dictionary is recreated on each iteration.

The following examples are contrived and just serve as a minimal repex.

Two things that do work as expected:

l = list()
for i in range(1, 4):
    d = dict()  # dict recreated on every iteration
    d['index'] = i
    l.append(d)
print(l)

print([{'index': i} for i in range(1, 4)])

They both print:

[{'index': 1}, {'index': 2}, {'index': 3}]

The thing that does not work as expected:

d = dict()  # dict created once only
l = list()
for i in range(1, 4):
    d['index'] = i
    l.append(d)
print(l)

Produces:

[{'index': 3}, {'index': 3}, {'index': 3}]

I'd have expected that the existing dictionary's value referred to by index would simply be overwritten on every pass and then added to the list and that I'd get a little performance improvement (in reality the dict is much larger).

It almost appears as if l.append just added references instead of passing values.

Am I missing something embarrassingly obvious?

pfabri
  • 885
  • 1
  • 9
  • 25

2 Answers2

2

"It almost appears as if l.append just added references instead of passing values.": That's it; you didn't miss anything.

Scott Hunter
  • 48,888
  • 12
  • 60
  • 101
1

Like other people said,Python will pass the reference.But you could do like:

for i in range(1, 4):
    d['index'] = i
    l.append(d.copy())

To get the result you want.

jizhihaoSAMA
  • 12,336
  • 9
  • 27
  • 49