3

The dict method {}.fromkeys() takes an iterable of strings, which will be transformed into dictionary keys. The default value will default to None. For instance:

d = {}.fromkeys(['loss', 'val_loss'])
{'loss': None, 'val_loss': None}

An optional, second argument is the default value that all these values will take:

d = {}.fromkeys(['loss', 'val_loss'], [])
{'loss': [], 'val_loss': []}

I understand that you can initialize an empty dict like this. Where it gets more complicated is that the default values point to the same object.

[id(val) for val in d.values()]
[140711273848032, 140711273848032]

If you would append one list, it would append all the values of this dict. Therefore, you need to re-assign the values to a new object in order to treat the dict values as separate objects:

d['loss'] = list([0.2, 0.4])

If you don't do that, you will change all dict values at the same time.

My question: what purpose is the optional default value intended to serve?

As I see it, you will need to reassign this default value anyway, unless you want to manipulate the same object with different dict keys. I can't think of an honest reason to have many dict keys for one object.

Nicolas Gervais
  • 33,817
  • 13
  • 115
  • 143
  • 4
    The purpose of the optional default value is to be a default value instead of `None`, as you observed. That this is the same object for every key is only problematic if it is a mutable object, like a list or dictionary. If you want a dictionary with a list or dictionary as default value if you look up a non existent key, you should use a `defaultdict` instead. – mkrieger1 Jun 02 '20 at 13:22
  • Does this answer your question? [dict.fromkeys all point to same list](https://stackoverflow.com/questions/15516413/dict-fromkeys-all-point-to-same-list) – mkrieger1 Jun 02 '20 at 13:25
  • Or https://stackoverflow.com/questions/654646/how-do-i-create-a-unique-value-for-each-key-using-dict-fromkeys – mkrieger1 Jun 02 '20 at 13:26
  • i know how to use a `defaultdict`, and that's not what i'm looking for. – Nicolas Gervais Jun 02 '20 at 13:27
  • 1
    From the [documentation](https://docs.python.org/3/library/stdtypes.html#dict) "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." – ywbaek Jun 02 '20 at 13:28
  • please stop the dupe-hammering. these do not answer my question. i know how to use dict comprehension to create new objects, and i know how to do this another way. the mutable part could be an answer to my question, however – Nicolas Gervais Jun 02 '20 at 13:32
  • 1
    Can you clarify what *is* your question? The part you've highlighted in bold has the obvious answer "the purpose is that you can specify the default value in case you don't like `None`". But I guess you know that from the documentation so I don't understand what is unclear to you. – mkrieger1 Jun 02 '20 at 13:39
  • you answered it pretty well in the second sentence of your first comment – Nicolas Gervais Jun 02 '20 at 13:43

1 Answers1

2

This can work ( dictionary comprehension)

keys = {'A', 'B', 'C'}
int_lst = [9]
a_dict = { key : list(int_lst) for key in keys }
print(a_dict)
a_dict['B'].append(12)
print(a_dict)
balderman
  • 22,927
  • 7
  • 34
  • 52