Is there a way to preserve duplicate keys in python dictionary

is there any way to store duplicate keys in a dictionary?

I have a specific requirement to form pairs of requests and responses.

Requests from a particular node to another particular node form same keys. I need to store both those.

But if I tried to add them to dictionary, first one is being replaced by second. Is there any way?

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

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'}

Method 2

While I’m not 100% sure, I’m pretty sure the answer is no. That sort of violates the purpose of a dictionary in python. How about you change the value to lists so instead of

{Key:value}

you have

{Key:[Value1,value2]}

Method 3

An alternative to the defaultdict might be

d = {}
d.setdefault(newkey, []).append(newvalue)

This does the same: append newvalue to a list which is either already in the dictionary at the given newkey, or if not, will be put there.

Method 4

There is no way to do this, no. Dictionaries rely on the keys being unique – otherwise, when you request or set a key, what value would be returned or overwritten?

What you could do, however, is store a list as the value for the dictionary, and then add your values to that list, rather than replacing the existing value.

You might want to use a collections.defaultdict to do this, to avoid making the lists by hand each time a new key is introduced.

Method 5

Use lists to store all values for the equal keys:

{a:b, a:c}  # foolish, won't work
{a: [ b, c ]}  # works like a charm!

You also might want to use

from collections import defaultdict
d = defaultdict(list)
d[a].append(b)

to fill your dictionary in an easy way.

Method 6

I like the answers using collections.defaultdict. That’s the way I would probably go.

But that assumes a dict or dict-like structure and a one-to-many mapping is the right solution. Rereading the question, the requirement to “form pairs of requests and responses” might lead to a simpler list-of-tuples (or list-of-lists) approach. E.g.:

pairs = []
pairs.append( (request, response) )

Which might create a list like:

[ ('GET /', 200), ('GET /index.html', 200), ('GET /x', 403), ('GET /', 200), ]

It’s only lightly structured, but depending on what you want to do with it, could be fine.

Method 7

A more elegant solution:

def add_to_dict(towhat, key, value):
    info = towhat.get(key, [])
    info.append(value)
    towhat[key] = info

alternate = {}

add_to_dict(alternate,"Andrew","Cambridge")
add_to_dict(alternate,"Barbara","Bloomsbury")
add_to_dict(alternate,"Andrew","Corsica")

print alternate

Method 8

A dictionary, by definition, requires that keys be unique identifiers. You can either:

  1. Use a different data structure such as a list or tuple that allows for duplicate entries.
  2. Use a unique identifier for your dictionary keys, much the same way that a database might use an auto-incrementing field for its key id.

If you are storing a lot of request/response pairs, you might be better off with a database anyway. It’s certainly something to consider.


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x