1
def stack_ov_test():
    my_set = set([1, 2, 1, 2, 3, 4, 3, 2, 3])
    my_dictionary = dict.fromkeys(my_set, [])
    my_dictionary[1].append(0)
    print(my_dictionary)  #  {1: [0], 2: [0], 3: [0], 4: [0]}

I think the code above is pretty much self-explanatory, and this is why this is bothering me that much. I simply want to create a dictionary out of a set / list and then add gradually data to each list of the keys. When referencing the list that I want to append to, all of the lists in the dictionary are being modified. Can somebody please explain me what I am missing? Thank you very much!

Small edit:

When I create the dictionary manually, everything works as usual:

def stack_ov_test():
    my_dictionary = {1: [], 2: [], 3: []}
    my_dictionary[1].append(0)
    print(my_dictionary)  #  {1: [0], 2: [], 3: []}
Adrian
  • 363
  • 3
  • 12

1 Answers1

1

The fromkeys() method with an empty list argument returns a dictionary with values that point to the exact same empty list, no matter which key. This makes the method not as useful as it could have been for this application (and confusing to more than a few users).

From the docs:

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.

When creating a dictionary manually, you assign a different copy of the empty list to values.

The preferred method is to use a dictionary comprehension:

def stack_ov_test():
    my_set = set([1, 2, 1, 2, 3, 4, 3, 2, 3])
    my_dict = {k: [] for k in my_set}
    print(my_dict) # {1: [], 2: [], 3: [], 4: []}
    my_dict[1].append(0)
    print(my_dict)  # {1: [0], 2: [], 3: [], 4: []}

stack_ov_test()    
Timur Shtatland
  • 12,024
  • 2
  • 30
  • 47