Я только что понял в комментариях, которые вы сказали, что вы не хотите создавать новый словарь, а хотите получить доступ к существующему x
через цепочку частей в списке.
(3.b) используйте for loop
, чтобы получить / установить значение в ключе путь
В случае, если вы хотите прочитать значение только в конце пути в
import copy
def get_val(key_list, dict_):
reduced = copy.deepcopy(dict_)
for i in range(len(key_list)):
reduced = reduced[key_list[i]]
return reduced
# this solution isn't mine, see the link below
def set_val(dict_, key_list, value_):
for key in key_list[:-1]:
dict_ = dict_.setdefault(key, {})
dict_[key_list[-1]] = value_
get_val()
Где список ключей - это результат string.slit('.')
, а dict_
- это словарь x
в вашем случае. Вы можете пропустить часть copy.deepcopy()
, это просто для параноидальных писков, как я - причина в том, что диктат python не является неизменным , таким образом, работает над глубокой копией (отдельным но точная копия в памяти) является решением. set_val()
Как я уже сказал, это не моя идея, кредит на @ Bakuriu
dict.setdefault(key, default_value)
позаботится о существующие ключи в x
.
(3) оценка строки как кода с eval()
и / или exec()
Итак, вот некрасивое небезопасное решение:
def chainer(key_list):
new_str = ''
for key in key_list:
new_str = "{}['{}']".format(new_str, key)
return new_str
x = {'request': {'context': {'user_id': 'is this what you are looking for?'}}}
keys = 'request.context.user_id'.split('.')
chained_keys = chainer(keys)
# quite dirty but you may use eval() to evaluate a string
print( eval("x{}".format(chained_keys)) )
# will print
is this what you are looking for?
, который является самым внутренним значением макета x
dict
Я предполагаю, что вы можете использовать это в своем коде, как это
data = [x for x in logData if eval("x{}".format(chained_keys)) in listX]
# or in python 3.x with f-string
data = [x for x in logData if eval(f"x{chained_keys}") in listX]
. ..или что-то похожее.
Аналогично, вы можете использовать exec()
для выполнения строки как кода, если хотите записать в x
, хотя это так же грязно и небезопасно.
exec("x{} = '...or this, maybe?'".format(chained_keys))
print(x)
# will print
{'request': {'context': {'user_id': '...or this, maybe?'}}}
(2) Фактическое решение может быть recursive function
следующим образом:
def nester(key_list):
if len(key_list) == 0:
return 'value' # can change this to whatever you like
else:
return {key_list.pop(0): nester(key_list)}
keys = 'request.context.user_id'.split('.')
# ['request', 'context', 'user_id']
data = nester(keys)
print(data)
# will result
{'request': {'context': {'user_id': 'value'}}}
(1) Решение с list comprehension
для разделить строку на '.' и использовать каждый элемент в списке в качестве словарного ключа
data = {}
parts = 'request.context.user_id'.split('.')
if parts: # one or more items
[data.update({part: 'value'}) for part in parts]
print(data)
# the result
{'request': 'value', 'context': 'value', 'user_id': 'value'}
Вы можете перезаписать значения в data
впоследствии.