2010-06-26 15 views
11

Tanto Google como los documentos en línea no brindan mucha información sobre mi consulta, así que pensé en preguntarle a la comunidad aquí.En un diccionario de dictados, ¿cómo se emula el comportamiento de auto-vivificación de Perl?

En Perl, se puede configurar fácilmente un hash-of-a-hash-of-a-hash y probar la clave final de este modo:

my $hash = {}; 
$hash{"element1"}{"sub1"}{"subsub1"} = "value1"; 
if (exists($hash{"element1"}{"sub1"}{"subsub1"})) { 
    print "found value\n"; 
} 

¿Cuál es el equivalente 'mejores prácticas' en Python ?

Respuesta

14

El equivalente más cercano es probablemente algo como lo siguiente:

import collections 

def hasher(): 
    return collections.defaultdict(hasher) 

hash = hasher() 
hash['element1']['sub1']['subsub1'] = 'value1' 
if 'subsub1' in hash['element1']['sub1']: 
    print 'found value' 
+3

Tenga en cuenta que 'si sub1 en hash ['phony']' crea una clave ''phony''. Esto podría ser problemático, especialmente dado que el OP desea probar si existen claves ... – unutbu

+0

@ ~ unutbu: el OP pregunta: "prueba la * clave * final", por lo tanto 'hash ['element1'] ['sub1'] = dict (subsub1 = 'value1') 'funcionará. – jfs

+0

Gracias, esto es bastante útil. – jbb

5

En cuanto a si esto es una buena práctica en Python es hasta Debate:

hash = {} 
hash['element1', 'sub1', 'subsub1'] = 'value' 
if ('element1', 'sub1', 'subsub1') in hash: 
    print "found value" 

Pero, desde luego, que funciona y es muy elegante, si funciona para ti.

El principal inconveniente es que no tiene acceso intermedio. Usted no puede hace:

if ('element1', 'sub1') in hash: 
    print "found value" 
+1

Debe explicar lo que está sucediendo. Este es un hash/dict único con una [tupla] de 3 elementos (http://docs.python.org/library/functions.html#tuple) como clave. Realmente no es lo mismo, aunque de alguna manera lo indicaste con tu segundo ejemplo. –

+0

Manera interesante de manejar el "inconveniente" (si lo considera así) en la respuesta de Alex Martelli, señalada por ~ unutbu. –

+0

De hecho, esto no era lo que estaba buscando, pero de todos modos era interesante. Gracias por el consejo. – jbb

0

no sé si voy a conseguir un acuerdo, pero así es como normalmente Declaro diccionarios de diccionarios:

someObj = { 
    'element1': { 
    'sub1': { 
     'subsub1': 'value1' 
    } 
    } 
} 

En cuanto a la comprobación de la presencia de un elemento, estoy de acuerdo con este enfoque:

try: 
    someObj['element1']['sub1']['subsub1'] 
except KeyError: 
    print('no value found') 
else: 
    print('found value') 
3
from collections import defaultdict 

tree = lambda: defaultdict(tree) 

t = tree() 

t[1][2][3] = 4 
t[1][3][3] = 5 
t[1][2]['test'] = 6 

de wikipedia Autovivification

+1

Además de usar 'lambda', ¿cómo es esto diferente de la respuesta aceptada hace 3 años? – MattH

Cuestiones relacionadas