Store path to dictionary value

爷,独闯天下 提交于 2019-12-22 12:07:30

问题


How might one store the path to a value in a dict of dicts? For instance, we can easily store the path to the name value in a variable name_field:

person = {}
person['name'] = 'Jeff Atwood'
person['address'] = {}
person['address']['street'] = 'Main Street'
person['address']['zip'] = '12345'
person['address']['city'] = 'Miami'

# Get name
name_field = 'name'
print( person[name_field] )

How might the path to the city value be stored?

# Get city
city_field = ['address', 'city']
print( person[city_field] )  // Obviously won't work!

回答1:


You can use reduce function to do this

print reduce(lambda x, y: x[y], city_field, person)

Output

Miami



回答2:


You can do:

path = ('address', 'city')
lookup = person
for key in path:
    lookup = lookup[key]

print lookup
# gives: Miami

This will raise a KeyError if a part of the path does not exist.

It will also work if path consists of one value, such as ('name',).




回答3:


An alternative that uses Simeon's (and Unubtu's deleted answer) is to create your own dict class that defines an extra method:

class mydict(dict):
    def lookup(self, *args):
        tmp = self
        for field in args:
            tmp = tmp[field]
        return tmp

person = mydict()
person['name'] = 'Jeff Atwood'
person['address'] = {}
person['address']['street'] = 'Main Street'
person['address']['zip'] = '12345'
person['address']['city'] = 'Miami'

print(person.lookup('address', 'city'))
print(person.lookup('name'))
print(person.lookup('city'))

which results in:

Miami
Jeff Atwood
Traceback (most recent call last):
  File "look.py", line 17, in <module>
    print(person.lookup('city'))
  File "look.py", line 5, in lookup
    tmp = tmp[field]
KeyError: 'city'

You can shorten the loop per the suggestion of thefourtheye. If you want to be really fancy, you can probably override private methods like __get__ to allow for a case like person['address', 'city'], but then things may become tricky.




回答4:


Here's another way - behaves exactly the same as Simeon Visser's

from operator import itemgetter
pget = lambda map, path: reduce(lambda x,p: itemgetter(p)(x), path, map)

With your example data:

person = {
  'name': 'Jeff Atwood',
  'address': {
    'street': 'Main Street',
    'zip': '12345',
    'city': 'Miami',
  },
}

pget(person, ('address', 'zip')) # Prints '12345'
pget(person, ('name',))          # Prints 'Jeff Atwood'
pget(person, ('nope',))          # Raises KeyError


来源:https://stackoverflow.com/questions/19812325/store-path-to-dictionary-value

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!