嵌套的dict键为变量

时间:2019-01-10 05:24:40

标签: python

必须有一种更优美的方法来执行此操作,但是我无法弄清楚如何创建一个函数来将值读/写到dict的不同级别,这是我能想到的“最佳”方法: / p>

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)

3 个答案:

答案 0 :(得分:2)

您可以使用* 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仅用作关键字,否则{p> *keys必须在参数列表中排第一,因为def put_any_level(*keys, value): get_any_level(*keys[:-1])[keys[-1]] = value 将使用所有位置参数。这不一定是一个不好的选择:

put_any_level(first, second1, value=17)

关键字参数增加了清晰度:

put_any_level(first, second1, 17)

但是,如果您尝试将其作为位置参数传递,也会导致错误,例如{{1}}。

次要点:

  1. 通常仅将CamelCase用于类名。变量和函数通常用lowercase_with_underscores编写。
  2. 一个函数通常应该做一件事,并且做得很好。在这种情况下,我将给嵌套函数赋予返回值,从而将查找嵌套值的任务与显示嵌套任务的任务分开了。

答案 1 :(得分:0)

这可以通过* args实现。进一步了解here

这是方法:

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)

答案 2 :(得分:0)

与其他建议类似,但如果您喜欢递归,则可能更为优美:

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

通常,递归可能很危险,因为它很昂贵-但由于您不太可能拥有难以置信的深度字典,因此我觉得这里是正确的解决方案。

相关问题