2010-06-26 1 views
11

Как Google, так и онлайн-документы не дают большого понимания моего запроса, поэтому я подумал, что попрошу сообщество здесь.В диктовке dicts, как вы эмулируете поведение Auto-vivification Perl?

В Perl, вы можете легко настроить хэш-в-а-хэш-в-а-хэш и протестировать последний ключ, как так:

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

Что такое «наилучшей практики» эквивалент в Python ?

ответ

14

Ближайший эквивалент, вероятно, что-то вроде следующего:

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

Обратите внимание, что 'if sub1 в hash ['phony']' создает ключ '' phony''. Это может быть проблематично, тем более, что OP хочет проверить, существуют ли ключи ... – unutbu

+0

@ ~ unutbu: OP спрашивает: «проверить * конечный * ключ», поэтому 'hash ['element1'] ['sub1'] = dict (subsub1 = 'value1') 'будет делать. – jfs

+0

Спасибо, это очень полезно. – jbb

5

Как это ли лучшая практика в Python до дискутировать:

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

Но, это, конечно, работает и очень элегантный, если он работает на вас.

Главный недостаток заключается в том, что у вас нет промежуточного доступа. Вы не можете сделать:

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

Вы должны объяснить, что происходит. Это один хэш/dict с 3-элементным [кортежем] (http://docs.python.org/library/functions.html#tuple) в качестве ключа. На самом деле это не то же самое, хотя вы несколько указали на это со своим вторым примером. –

+0

Интересный способ справиться с «недостатком» (если вы считаете, что это так) в ответе Алекса Мартелли, на который указывает ~ unutbu. –

+0

Действительно, это было не то, что я искал, но тем не менее интересно. Спасибо за совет. – jbb

0

Я не знаю, буду ли я получить какое-либо соглашение, но это, как правило, я объявляю словари словарей:

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

Что касается проверки наличие элемента, я согласен с этим подходом:

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 

от wikipedia Autovivification

+1

Помимо использования 'lambda', как это отличается от принятого ответа 3 года назад? – MattH