Должен быть более изящный способ сделать это, но я не могу понять, как создать единую функцию для чтения / записи значений на разные уровни dict, это «лучшее», что я мог придумать:
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)
@TrebuchetMS, оба вопроса касаются словарей, но этот вопрос конкретно о том, как получить доступ к значению на произвольном уровне словаря.






Вы можете использовать * 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 должен стоять первым в списке аргументов, если вы не хотите, чтобы он содержал только ключевые слова, потому что *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).
Пара второстепенных моментов:
Это лучший ответ, чем мой.
@ Адитья. Я ценю то, что ты это говоришь.
@MadPhysicist - спасибо за объяснение. * args был ключом! Также оцените советы по соглашениям - новый язык - новые соглашения.
@MattYYC рад, что вам понравилось. Вы можете выбрать ответ, нажав на галочку рядом с ним.
Этого можно добиться с помощью * 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)
Под x = table[first] вы имели в виду x = table[argv[0]]?
@MadPhysicist Сейчас изменил. Спасибо.
Спасибо @AdityaK! Этот также был хорошим объяснением * args
Подобно другим предложениям, но, возможно, даже более изящно, если вам нравится рекурсия:
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
Обычно рекурсия может быть опасной, так как это дорого, но поскольку у вас вряд ли будут невероятно глубокие словари, я считаю, что это правильное решение.
Спасибо @Grismar - очень лаконично. Является ли [1:] эквивалентом popitems ()? Не уверен, что это значит.
[1:] означает «все элементы из последовательности, начиная с элемента с индексом 1». Итак, для x = [1,2,3,4], x[1:] будет [2,3,4] - подробнее об этом здесь, называется «нарезка». pythoncentral.io/how-to-slice-listsarrays-and-tuples-in-pyth на Это не эквивалент popitem(), не только потому, что он возвращает большую часть последовательности, но и, что более важно, потому что он не изменяет оригинал. - возвращает копию своего содержимого.
Не точный обман, но в какой-то степени связанный: stackoverflow.com/questions/1373164/…