简体   繁体   中英

How to address a dictionary in a list of ordered dicts by unique key value?

(Using Python 2.7) The list, for example:

L = [
    {'ID': 1, 'val': ['eggs']}, 
    {'ID': 2, 'val': ['bacon']}, 
    {'ID': 6, 'val': ['sausage']},
    {'ID': 9, 'val': ['spam']}
    ]

This does what I want:

def getdict(list, dict_ID):
    for rec in list
        if rec['ID'] == dict_ID:
            return rec

print getdict(L, 6)

but is there a way to address that dictionary directly, without iterating over the list until you find it?

The use case: reading a file of records (ordered dicts). Different key values from records with a re-occurring ID must be merged with the record with the first occurrence of that ID.

ID numbers may occur in other key values, so if rec['ID'] in list would produce false positives.

While reading records (and adding them to the list of ordered dicts), I maintain a set of unique ID's and only call getdict if a newly read ID is already in there. But then still, it's a lot of iterations and I wonder if there isn't a better way.

The use case: reading a file of records (ordered dicts). Different key values from records with a re-occurring ID must be merged with the record with the first occurrence of that ID.

You need to use a defaultdict for this:

>>> from collections import defaultdict
>>> d = defaultdict(list)
>>> d['a'].append(1)
>>> d['a'].append(2)
>>> d['b'].append(3)
>>> d['c'].append(4)
>>> d['b'].append(5)
>>> print(d['a'])
[1, 2]
>>> print(d)
defaultdict(<type 'list'>, {'a': [1, 2], 'c': [4], 'b': [3, 5]})

If you want to store other objects, for example a dictionary, just pass that as the callable:

>>> d = defaultdict(dict)
>>> d['a']['values'] = []
>>> d['b']['values'] = []
>>> d['a']['values'].append('a')
>>> d['a']['values'].append('b')
>>> print(d)
defaultdict(<type 'dict'>, {'a': {'values': ['a', 'b']}, 'b': {'values': []}})

Maybe I'm missing something, but couldn't you use a single dictionary?

L = {
    1 : 'eggs', 
    2 : 'bacon', 
    6 : 'sausage',
    9 : 'spam'
    }

Then you can do L.get(ID) . This will either return the value (eggs, etc) or None if the ID isn't in the dict.

You seem to be doing an inverse dictionary lookup, that is a lookup by value instead of a key. Inverse dictionary lookup - Python has some pointers on how to do this efficiently.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM