Make a dictionary with duplicate keys in Python

后端 未结 7 1073
野的像风
野的像风 2020-11-22 00:37

I have the following list which contains duplicate car registration numbers with different values. I want to convert it into a dictionary which accepts this multiple keys of

相关标签:
7条回答
  • 2020-11-22 00:50

    You can refer to the following article: http://www.wellho.net/mouth/3934_Multiple-identical-keys-in-a-Python-dict-yes-you-can-.html

    In a dict, if a key is an object, there are no duplicate problems.

    For example:

    class p(object):
        def __init__(self, name):
            self.name = name
        def __repr__(self):
            return self.name
        def __str__(self):
            return self.name
    d = {p('k'): 1, p('k'): 2}
    
    0 讨论(0)
  • 2020-11-22 00:55

    If you want to have lists only when they are necessary, and values in any other cases, then you can do this:

    class DictList(dict):
        def __setitem__(self, key, value):
            try:
                # Assumes there is a list on the key
                self[key].append(value)
            except KeyError: # If it fails, because there is no key
                super(DictList, self).__setitem__(key, value)
            except AttributeError: # If it fails because it is not a list
                super(DictList, self).__setitem__(key, [self[key], value])
    

    You can then do the following:

    dl = DictList()
    dl['a']  = 1
    dl['b']  = 2
    dl['b'] = 3
    

    Which will store the following {'a': 1, 'b': [2, 3]}.


    I tend to use this implementation when I want to have reverse/inverse dictionaries, in which case I simply do:

    my_dict = {1: 'a', 2: 'b', 3: 'b'}
    rev = DictList()
    for k, v in my_dict.items():
        rev_med[v] = k
    

    Which will generate the same output as above: {'a': 1, 'b': [2, 3]}.


    CAVEAT: This implementation relies on the non-existence of the append method (in the values you are storing). This might produce unexpected results if the values you are storing are lists. For example,

    dl = DictList()
    dl['a']  = 1
    dl['b']  = [2]
    dl['b'] = 3
    

    would produce the same result as before {'a': 1, 'b': [2, 3]}, but one might expected the following: {'a': 1, 'b': [[2], 3]}.

    0 讨论(0)
  • 2020-11-22 01:07

    You can change the behavior of the built in types in Python. For your case it's really easy to create a dict subclass that will store duplicated values in lists under the same key automatically:

    class Dictlist(dict):
        def __setitem__(self, key, value):
            try:
                self[key]
            except KeyError:
                super(Dictlist, self).__setitem__(key, [])
            self[key].append(value)
    

    Output example:

    >>> d = dictlist.Dictlist()
    >>> d['test'] = 1
    >>> d['test'] = 2
    >>> d['test'] = 3
    >>> d
    {'test': [1, 2, 3]}
    >>> d['other'] = 100
    >>> d
    {'test': [1, 2, 3], 'other': [100]}
    
    0 讨论(0)
  • 2020-11-22 01:08

    You can't have duplicated keys in a dictionary. Use a dict of lists:

    for line in data_list:
      regNumber = line[0]
      name = line[1]
      phoneExtn = line[2]
      carpark = line[3].strip()
      details = (name,phoneExtn,carpark)
      if not data_dict.has_key(regNumber):
        data_dict[regNumber] = [details]
      else:
        data_dict[regNumber].append(details)
    
    0 讨论(0)
  • 2020-11-22 01:12

    You can't have a dict with duplicate keys for definition! Instead you can use a single key and, as value, a list of elements that had that key.

    So you can follow these steps:

    1. See if the current element's (of your initial set) key is in the final dict. If it is, go to step 3
    2. Update dict with key
    3. Append the new value to the dict[key] list
    4. Repeat [1-3]
    0 讨论(0)
  • 2020-11-22 01:13

    I just posted an answer to a question that was subequently closed as a duplicate of this one (for good reasons I think), but I'm surprised to see that my proposed solution is not included in any of the answers here.

    Rather than using a defaultdict or messing around with membership tests or manual exception handling, you can easily append values onto lists within a dictionary using the setdefault method:

    results = {}                              # use a normal dictionary for our output
    for k, v in some_data:                    # the keys may be duplicates
        results.setdefault(k, []).append(v)   # magic happens here!
    

    This is a lot like using a defaultdict, but you don't need a special data type. When you call setdefault, it checks to see if the first argument (the key) is already in the dictionary. If doesn't find anything, it assigns the second argument (the default value, an empty list in this case) as a new value for the key. If the key does exist, nothing special is done (the default goes unused). In either case though, the value (whether old or new) gets returned, so we can unconditionally call append on it, knowing it should always be a list.

    0 讨论(0)
提交回复
热议问题