Какой лучший способ инициализировать диктофон в Python?

Много раз в Perl я сделаю что-то вроде этого:

$myhash{foo}{bar}{baz} = 1

Как перевести это на Python? До сих пор я:

if not 'foo' in myhash:
    myhash['foo'] = {}
if not 'bar' in myhash['foo']:
    myhash['foo']['bar'] = {}
myhash['foo']['bar']['baz'] = 1

Есть ли лучший способ?

Ответ 1

class AutoVivification(dict):
    """Implementation of perl autovivification feature."""
    def __getitem__(self, item):
        try:
            return dict.__getitem__(self, item)
        except KeyError:
            value = self[item] = type(self)()
            return value

Тестирование:

a = AutoVivification()

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

print a

Вывод:

{1: {2: {'test': 6, 3: 4}, 3: {3: 5}}}

Ответ 2

Если количество вложенности, которое вам нужно, исправлено, collections.defaultdict замечательно.

например. вложенные две глубины:

myhash = collections.defaultdict(dict)
myhash[1][2] = 3
myhash[1][3] = 13
myhash[2][4] = 9

Если вы хотите перейти на другой уровень вложенности, вам нужно сделать что-то вроде:

myhash = collections.defaultdict(lambda : collections.defaultdict(dict))
myhash[1][2][3] = 4
myhash[1][3][3] = 5
myhash[1][2]['test'] = 6

edit: MizardX указывает, что мы можем получить полную универсальность с помощью простой функции:

import collections
def makehash():
    return collections.defaultdict(makehash)

Теперь мы можем сделать:

myhash = makehash()
myhash[1][2] = 4
myhash[1][3] = 8
myhash[2][5][8] = 17
# etc

Ответ 3

Есть ли причина, по которой он должен быть диктофоном? Если нет какой-либо убедительной причины для этой конкретной структуры, вы можете просто индексировать dict с помощью кортежа:

mydict = {('foo', 'bar', 'baz'):1} # Initializes dict with a key/value pair
mydict[('foo', 'bar', 'baz')]      # Returns 1

mydict[('foo', 'unbar')] = 2       # Sets a value for a new key

Скобки необходимы, если вы инициализируете dict с помощью кортежа, но можете их опустить при настройке/получении значений с помощью []:

mydict = {}                        # Initialized the dict
mydict['foo', 'bar', 'baz'] = 1    # Sets a value
mydict['foo', 'bar', 'baz']        # Returns 1

Ответ 4

Я предполагаю, что буквальный перевод будет:

 mydict = {'foo' : { 'bar' : { 'baz':1}}}

Призвание:

 >>> mydict['foo']['bar']['baz']

дает вам 1.

Это выглядит немного грубо для меня.

(я не человек perl, хотя, поэтому я угадываю, что делает ваш perl)

Ответ 5

Вложенные словари, подобные этим (часто), называются плохими объектами. Да, есть импликация, и она может коррелировать с объектно-ориентированной природой pythons.