E 'abbastanza brutto, ma questo funziona:
def set_val(d, keys, val):
reduce(lambda x,y: x[y], keys[:-1], d)[keys[-1]] = val
versione leggermente più leggibile:
def set_val(d, keys, val):
last = keys[-1] # Key we want to set val on
search_keys = keys[:-1] # Keys we need to traverse
reduce(lambda x,y: x[y], search_keys, d)[last] = val
Uso:
>>> from collections import defaultdict
>>> D = lambda: defaultdict(D)
>>> d = D()
>>> set_val(d, ['k1', 'k2', 'k3'], "hi")
>>> d
defaultdict(<function <lambda> at 0x7fbd365ac7d0>, {'k1': defaultdict(<function <lambda> at 0x7fbd365ac7d0>, {'k2': defaultdict(<function <lambda> at 0x7fbd365ac7d0>, {'k3': 'hi'})})})
>>> d['k1']['k2']['k3']
'hi'
utilizza reduce
per raggiungere il più interno dict chiesto (keys[:-1]
), quindi imposta la chiave finale nella lista al valore desiderato (output_of_reduce[keys[-1]] = val
).
Si noti che in Python 3 è necessario un numero da functools import reduce
per utilizzare questo.
Ecco il codice esteso per chiarezza:
def set_val(d, keys, val):
out = d
for k in keys[:-1]:
out = out[k]
out[keys[-1]] = val
Buona ricerca @Dave. La tua ricerca è meglio della ricerca SO di domande correlate. – Gerrat
In effetti una buona scoperta. Chiudere la mia stessa domanda come duplicato ... :) – wim