Python 作为变量的嵌套dict键
必须有一种更优雅的方法来实现这一点,但我不知道如何创建一个函数来读取/写入dict的不同级别的值,这是我能想到的“最佳”方法:Python 作为变量的嵌套dict键,python,Python,必须有一种更优雅的方法来实现这一点,但我不知道如何创建一个函数来读取/写入dict的不同级别的值,这是我能想到的“最佳”方法: table = { 'A': { 'B': '2', 'C': { 'D':'3' } } } first = 'A' second1 = 'B' second2 = 'C' third = 'D' def oneLevelDict(first): x = table[fi
table = {
'A': {
'B': '2',
'C': {
'D':'3'
}
}
}
first = 'A'
second1 = 'B'
second2 = 'C'
third = 'D'
def oneLevelDict(first):
x = table[first]
print(x)
def twoLevelDict(first, second):
x = table[first][second]
print(x)
def threeLevelDict(first, second, third):
x = table[first][second][third]
print(x)
oneLevelDict(first)
twoLevelDict(first, second1)
threeLevelDict(first, second2, third)
可以使用*args向函数传递任意数量的参数。然后可以使用循环遍历标高
get_any_level(*keys):
d = table
for key in keys:
d = d[key]
return d
现在,您有一个功能可以取代以前的三个功能:
print(get_any_level(first))
print(get_any_level(first, second1))
print(get_any_level(first, second2, third))
您也可以使用此函数写入任意级别:
get_any_level(first)[second1] = 17
更好的方法可能是使用单独的函数来编写:
def put_any_level(value, *keys):
get_any_level(*keys[:-1])[keys[-1]] = value
put_any_level(17, first, second1)
value
必须位于参数列表的第一位,除非您希望它仅为关键字,因为*键将使用所有位置参数。这不一定是一个坏的选择:
def put_any_level(*keys, value):
get_any_level(*keys[:-1])[keys[-1]] = value
关键字参数增加了清晰度:
put_any_level(first, second1, value=17)
但是,如果试图将其作为位置参数传递,也会导致错误,例如,将其置于任何级别(第一、第二、17)
几个小问题:
通常只对类名使用CamelCase。变量和函数通常用小写字母_加下划线表示
函数通常应该做一件事,并且做得很好。在本例中,我通过给函数一个返回值,将查找嵌套值的任务与显示嵌套值的任务分开
这可以使用*args实现。阅读更多关于它的信息
这就是如何做到这一点:
def allLevelDict(*argv):
if len(argv) == 1:
x = table[argv[0]]
print (x)
elif len(argv) == 2:
x = table[argv[0]][argv[1]]
print (x)
elif len(argv) == 3:
x = table[argv[0]][argv[1]][argv[2]]
print (x)
allLevelDict(first)
allLevelDict(first, second1)
allLevelDict(first, second2, third)
与其他建议类似,但如果您喜欢递归,可能会更优雅:
table = {'A':{'B':'2','C':{'D':'3'}}}
first = 'A'
second1 = 'B'
second2 = 'C'
third = 'D'
def get_from(x, *keys):
return get_from(x[keys[0]], *keys[1:]) if len(keys) > 0 else x
print(get_from(table, first))
print(get_from(table, first, second1))
print(get_from(table, first, second2, third))
注意:我也在传递表格,因为我想你也希望能在其他字典上使用它
或者,如果你认为越短越好:
def get_from(x, *keys):
if len(keys) > 0
return get_from(x[keys[0]], *keys[1:])
else:
return x
通常情况下,递归可能是危险的,因为它很昂贵——但因为你不太可能有非常深刻的字典,我觉得这是正确的解决方案。不是一个完全的骗局,但在某种程度上是相关的:@TrebuchetMS,这两个问题都是关于字典的,但这个问题是关于如何在字典的任意级别访问值的。这是一个比我的更好的答案。@Aditya。我很感激你这么说。@MadPhysicator-谢谢你解释这一点*阿格斯是关键!也要欣赏会议技巧-新语言-新会议。@MattYYC很高兴你喜欢它。您可以通过单击旁边的复选标记来选择答案。通过x=table[first]
您的意思是x=table[argv[0]]
?@madpysicator现在更改了它。谢谢。谢谢@AdityaK!也是对*argsThanks@Grismar的一个很好的解释-非常简洁。[1:]是否等效于popitems()?不确定这是什么意思。[1:://code>表示“序列中的所有元素,从索引1处的元素开始”。因此,对于x=[1,2,3,4]
,x[1:]
将是[2,3,4]
-在这里阅读更多关于这一点的内容,称为“切片”,它不等同于popitem()
,不仅因为它返回序列的更大部分,更重要的是因为它不修改原始内容,而是返回其内容的副本。