2010-11-04 6 views
1

i besoin de recueillir quelques données de complext dict basé sur Dot notation des noms clésfaçon pythonique de recueillir des données spécifiques de dict complexes

par exemple

données d'échantillon

data = { 
    'name': {'last': 'smith', 'first': 'bob'}, 
    'address':{'city': 'NY', 'state': 'NY'}, 
    'contact':{'phone':{'self':'1234', 'home':'222'}}, 
    'age':38, 
    'other':'etc' 
} 

keys = ['contact.phone.self', 'name.last', 'age'] 

ma logique

result = [] 
for rev_key in rev_keys: 
    current = data.copy() 
    rev_key = rev_key.split('.') 
    while rev_key: 
    value = rev_key.pop(0) 
    current = current[value] 
    result.append(current) 

Merci d'avance!

+1

Ne jamais utiliser un nom de classe comme nom de variable. Veuillez corriger l'exemple pour éviter d'utiliser 'dict' comme variable. C'est une erreur terrible. –

Répondre

4
[reduce(dict.get, key.split("."), data) for key in keys] 
+0

pfffiuu! J'ai à peine compris comment reduce() fonctionne sur un dictionnaire, mais je l'ai finalement obtenu. Solution admirable. +1 n'est pas suffisant – eyquem

0

Que pensez-vous de cela?

def fetch(some_dict, key_iter): 
    for key in key_iter: 
     subdict= some_dict 
     for field in key.split('.'): 
      subdict = subdict[field] 
     yield subdict 

a_dict = { 
    'name': {'last': 'smith', 'first': 'bob'}, 
    'address':{'city': 'NY', 'state': 'NY'}, 
    'contact':{'phone':{'self':'1234', 'home':'222'}}, 
    'age':38, 
    'other':'etc' 
} 

keys = ['contact.phone.self', 'name.last', 'age'] 

result = list(fetch(a_dict, keys)) 
0

Voilà ma fissure à elle:

>>> def find(tree,cur): 
    if len(cur)==1: 
     return tree[cur[0]] 
    else: 
     return find(tree[cur[0]],cur[1:]) 


>>> print [find(data,k.split(".")) for k in keys] 
['1234', 'smith', 38] 

Bien sûr, cela causera des débordements de pile si les éléments sont trop profondément imbriqués (à moins que vous soulevez explicitement la profondeur de récursivité), et je voudrais utiliser un deque au lieu d'un list s'il s'agissait d'un code de production.

0

Il suffit d'écrire une fonction qui obtient une touche à la fois

def getdottedkey(data, dottedkey): 
    for key in dottedkey.split('.'): 
     data = data[key] 
    return data 

print [getdottedkey(data, k) for k in keys] 
Questions connexes