1
a = 'aa'
iss = ['1', '2', '3', '4']
swhls = dict.fromkeys(iss, {a: None})

for i in iss:
    swhls[i][a] = i
print(swhls)

This iteration produces wrong results.

The result is:

{'1': {'aa': '4'}, '2': {'aa': '4'}, '3': {'aa': '4'}, '4': {'aa': '4'}}

However I expected:

{'1': {'aa': '1'}, '2': {'aa': '2'}, '3': {'aa': '3'}, '4': {'aa': '4'}}
mozway
  • 194,879
  • 13
  • 39
  • 75
Kamil
  • 21
  • 5

1 Answers1

4

By doing dict.fromkeys(iss, {a: None}) you set all values to be the same object.

[id(v) for v in dict.fromkeys(iss, {a: None}).values()]

# [140236495531968, 140236495531968, 140236495531968, 140236495531968]

Thus the final value is that of the last iteration.

This is actually well described in the dict.fromkeys documentation:

classmethod fromkeys(iterable[, value])

Create a new dictionary with keys from iterable and values set to value.

fromkeys() is a class method that returns a new dictionary. value defaults to None. All of the values refer to just a single instance, so it generally doesn’t make sense for value to be a mutable object such as an empty list. To get distinct values, use a dict comprehension instead.

Use a dictionary comprehension to assign a new object to each key:

a = 'aa'
iss = ['1', '2', '3', '4']
swhls = {x: {a: None} for x in iss}

for i in iss:
    swhls[i][a] = i
print(swhls)

Output:

{'1': {'aa': '1'}, '2': {'aa': '2'}, '3': {'aa': '3'}, '4': {'aa': '4'}}
mozway
  • 194,879
  • 13
  • 39
  • 75