如何在字典中存储值的路径

2024-06-05 13:57:16 浏览数 (2)

在Python中,你可以使用嵌套字典(或其他可嵌套的数据结构,如嵌套列表)来存储值的路径。例如,如果你想要存储像这样的路径和值:

1、问题背景

在 Python 中,我们可以轻松地使用字典来存储数据。字典是一种无序的键值对集合,键可以是任意字符串,值可以是任意类型的数据。我们还可以使用字典来存储其他字典,这样就形成了一个嵌套字典。

有时候,我们需要存储一个字典中值的路径。例如,我们想存储 name 值的路径,我们可以使用一个变量 name_field 来存储这个路径:

代码语言:javascript复制
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] )

这样,我们就可以通过 name_field 来获取 name 值。但是,如果我们需要存储 city 值的路径呢?我们不能直接使用一个变量 city_field 来存储这个路径,因为 city 值是一个嵌套字典中的值。

代码语言:javascript复制
# Get city
city_field = ['address', 'city']
print( person[city_field] )  # Obviously won't work!

2、解决方案

有几种方法可以存储字典中值的路径。

第一种方法是使用循环。我们可以使用一个循环来遍历路径中的每个键,然后使用这些键来获取值。例如,我们可以使用以下代码来获取 city 值:

代码语言:javascript复制
path = ('address', 'city')
lookup = person
for key in path:
    lookup = lookup[key]
​
print lookup

这种方法很简单,但是它有一个缺点:如果路径中的任何一个键不存在,它都会引发一个 KeyError 异常。

第二种方法是使用 reduce 函数。我们可以使用 reduce 函数来将一个路径中的所有键组合成一个函数,然后使用这个函数来获取值。例如,我们可以使用以下代码来获取 city 值:

代码语言:javascript复制
print reduce(lambda x, y: x[y], city_field, person)

这种方法比第一种方法更简洁,但是它有一个缺点:它只适用于路径中的键都是字符串的情况。

第三种方法是使用自定义字典类。我们可以创建一个自己的字典类,并在其中定义一个新的方法来获取值的路径。例如,我们可以使用以下代码来创建自定义字典类:

代码语言:javascript复制
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'))

这种方法是最灵活的,但是它也是最复杂的。

第四种方法是使用 operator.itemgetter 函数。我们可以使用 operator.itemgetter 函数来将一个路径中的所有键组合成一个函数,然后使用这个函数来获取值。例如,我们可以使用以下代码来获取 city 值:

代码语言:javascript复制
from operator import itemgetter
pget = lambda map, path: reduce(lambda x,p: itemgetter(p)(x), path, map)
​
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

这种方法与第二种方法非常相似,但是它更简洁。

这种方法的优点是它提供了一种结构化的方式来存储数据,使得路径和值之间的关系更加清晰。但是,需要注意的是,如果路径结构很深或者路径很长,这种方法可能会变得不太方便。

所以说具体的情况还要根据公司具体的项目要求,然后根据自己的项目效果来做调整,今天的分享就到这里,

0 人点赞