Make a Dictionary With Duplicate Keys in Python

How to write Dictionary from list with Duplicate Keys

You can use collections.defaultdict or use dict.setdefault to have shorter code:

input_list = [[1, "a"], [1, "b"], [2, "c"], [2, "d"]]

out = {}
for k, v in input_list:
out.setdefault(k, []).append(v)

print(out)

Prints:

{1: ['a', 'b'], 2: ['c', 'd']}

How to make a dictionary with duplicate keys as integers in python with lists

Upfront, the first version is not possible, the entire concept behind a dict (and more generally an associative array) is that each key is associated with one value.

There are "multimaps" which map one key to multiple values, generally they'll do something like option 2, internally they'll just map keys to lists of values, then provide an interface to retrieve either individual or multiple values.

Anyway as for your second version, it seems relatively straightforward, what's your issue? You just have to zip() the two lists together, and append each new value, ensuring the key is mapped to at least an empty list:

out = {}
for key, value in zip(binaries, positions):
out.setdefault(key, []).append(value)

If there is no value for key, setdefault will set it to an empty list. This means we can always append new values without further complication.

Alternatively, out could be a defaultdict doing that same thing "under the cover".

For a bit more verbosity up-front, it's convenient if you control the entire lifecycle of the mapping (it can have unexpected side-effects otherwise) and would probably be more efficient:

out = collections.defaultdict(list)
for key, value in zip(binaries, positions):
out[key].append(value)

Is there a way to preserve duplicate keys in python dictionary

I can think of two simple options, assuming you want to keep using a dictionary.

  1. You could map keys to lists of items. A defaultdict from the collections module makes this easy.

    >>> import collections
    >>> data = collections.defaultdict(list)
    >>> for k, v in (('a', 'b'), ('a', 'c'), ('b', 'c')):
    ... data[k].append(v)
    ...
    >>> data
    defaultdict(<type 'list'>, {'a': ['b', 'c'], 'b': ['c']})
  2. You could use additional data to disambiguate the keys. This could be a timestamp, a unique id number, or something else. This has the advantage of preserving a one-to-one relationship between keys and values, and the disadvantage of making lookup more complex, since you always have to specify an id. The example below shows how this might work; whether it's good for you depends on the problem domain:

    >>> for k, v in (('a', 'b'), ('a', 'c'), ('b', 'c')):
    ... i = 0
    ... while (k, i) in data:
    ... i += 1
    ... data[(k, i)] = v
    ...
    >>> data
    {('a', 1): 'c', ('b', 0): 'c', ('a', 0): 'b'}

How to convert a list to dict with duplicate keys?

You solution is pretty good. list/dictionary comprehensions are not always the best approach. But If you insist, you can do something like:

from itertools import groupby

lst = [(1, 'a'), (2, 'b'), (2, 'c'), (3, 'd')]

res = {k: [b for a, b in g] for k, g in groupby(lst, key=lambda x: x[0])}
print(res)

output:

{1: ['a'], 2: ['b', 'c'], 3: ['d']}

note: This solution would work if you pass a sorted list, If it's not, make sure you sort the list before using it in the dictionary comprehension (Thanks @Chepner)

sorted_lst = sorted(lst, key=lambda x: x[0])


Related Topics



Leave a reply



Submit