3

Good day all,

I am trying to convert a list of length-2 items to a dictionary using the below:

my_list = ["b4", "c3", "c5"]
my_dict = {key: value for (key, value) in my_list}

The issue is that when a key occurrence is more than one in the list, only the last key and its value are kept.

So in this case instead of

my_dict = {'c': '3', 'c': '5', 'b': '4'}

I get

my_dict = {'c': '5', 'b': '4'}

How can I keep all key:value pairs even if there are duplicate keys. Thanks

Archie
  • 115
  • 1
  • 3
  • 10

3 Answers3

10

For one key in a dictionary you can only store one value.

You can chose to have the value as a list.

{'b': ['4'], 'c': ['3', '5']}

following code will do that for you :

new_dict = {}
for (key, value) in my_list:
    if key in new_dict:
        new_dict[key].append(value)
    else:
        new_dict[key] = [value]
print(new_dict)
# output: {'b': ['4'], 'c': ['3', '5']}

Same thing can be done with setdefault. Thanks @Aadit M Shah for pointing it out

new_dict = {}
for (key, value) in my_list:
    new_dict.setdefault(key, []).append(value)
print(new_dict)
# output: {'b': ['4'], 'c': ['3', '5']}

Same thing can be done with defaultdict. Thanks @MMF for pointing it out.

from collections import defaultdict
new_dict = defaultdict(list)
for (key, value) in my_list:
    new_dict[key].append(value)
print(new_dict)
# output: defaultdict(<class 'list'>, {'b': ['4'], 'c': ['3', '5']})

you can also chose to store the value as a list of dictionaries:

[{'b': '4'}, {'c': '3'}, {'c': '5'}]

following code will do that for you

new_list = [{key: value} for (key, value) in my_list]
Vikash Singh
  • 13,213
  • 8
  • 40
  • 70
2

If you don't care about the O(n^2) asymptotic behaviour you can use a dict comprehension including a list comprehension:

>>> {key: [i[1] for i in my_list if i[0] == key] for (key, value) in my_list}
{'b': ['4'], 'c': ['3', '5']}

or the iteration_utilities.groupedby function (which might be even faster than using collections.defaultdict):

>>> from iteration_utilities import groupedby
>>> from operator import itemgetter
>>> groupedby(my_list, key=itemgetter(0), keep=itemgetter(1))
{'b': ['4'], 'c': ['3', '5']}
MSeifert
  • 145,886
  • 38
  • 333
  • 352
  • 1
    There's `itertools.groupby`, but "_Generally, the iterable needs to already be sorted on the same key function._" That makes the function almost useless. – Abhijit Sarkar Sep 13 '21 at 09:16
1

You can use defaultdict to avoid checking if a key is in the dictionnary or not :

from collections import defaultdict

my_dict = defaultdict(list)
for k, v in my_list:
    my_dict[k].append(v)

Output :

defaultdict(list, {'b': ['4'], 'c': ['3', '5']})
Aadit M Shah
  • 72,912
  • 30
  • 168
  • 299
MMF
  • 5,750
  • 3
  • 16
  • 20