2013-12-06 7 views
39

Как я могу преобразовать defaultdictPython: конвертировать defaultdict в Сыроватского

number_to_letter 
defaultdict(<class 'list'>, {'2': ['a'], '3': ['b'], '1': ['b', 'a']}) 

быть общим ДИКТ?

{'2': ['a'], '3': ['b'], '1': ['b', 'a']} 
+7

'dict (number_to_letter)' –

+2

@TimPeters, поскольку на самом деле это хорошо написанный вопрос с очевидным заголовком (и должен легко отображаться в результатах поиска), для будущей ссылки было бы целесообразно поставить это в качестве ответа, если мы не может найти обман, который лучше ... –

+0

Этот ответ должен помочь: http://stackoverflow.com/a/3031915/1628832 – karthikr

ответ

57

Вы можете просто позвонить dict:

>>> a 
defaultdict(<type 'list'>, {'1': ['b', 'a'], '3': ['b'], '2': ['a']}) 
>>> dict(a) 
{'1': ['b', 'a'], '3': ['b'], '2': ['a']} 

, но помните, что defaultdict является ДИКТ:

>>> isinstance(a, dict) 
True 

только с немного различным поведением, в том, что при попытке доступа отсутствующий ключ - который обычно поднимает KeyError - default_factory называется instea d:

>>> a.default_factory 
<type 'list'> 

Это то, что вы видите, когда вы print a до появления на стороне данных словаря.

Так еще один трюк, чтобы получить больше поведение dictlike назад, фактически делает новый объект для сброса default_factory:

>>> a.default_factory = None 
>>> a[4].append(10) 
Traceback (most recent call last): 
    File "<ipython-input-6-0721ca19bee1>", line 1, in <module> 
    a[4].append(10) 
KeyError: 4 

, но большую часть времени это не стоит.

+0

Я только начинаю изучать программирование с помощью Python. Можете ли вы объяснить, как использовать 'default_factory'? Я просто не знаю, что происходит. Сожалею. – user2988464

+0

А что такое «KeyError»? – user2988464

+2

@ user2988464: вы уже использовали 'default_factory' - это функция, которую вы передали, когда вы сделали' defaultdict' в первую очередь, например 'defaultdict (int)' или 'defaultdict (list)'. Всякий раз, когда вы пытаетесь найти ключ в словаре, например 'a ['3']', например, в обычном словаре вы либо получаете значение, либо генерируете исключение KeyError (например, ошибку, сообщая вам об этом не удалось найти этот ключ).Но в 'defaultdict' вместо этого он вызывает функцию' default_factory' для * make * нового значения по умолчанию (это «default» в 'defaultdict') для вас. – DSM

3

Если вы даже хотите рекурсивную версию для преобразования рекурсивных defaultdict в dict вы можете попробовать следующее:

#! /usr/bin/env python3 

from collections import defaultdict 

def ddict(): 
    return defaultdict(ddict) 

def ddict2dict(d): 
    for k, v in d.items(): 
     if isinstance(v, dict): 
      d[k] = ddict2dict(v) 
    return dict(d) 

myddict = ddict() 

myddict["a"]["b"]["c"] = "value" 

print(myddict) 

mydict = ddict2dict(myddict) 

print(mydict) 
+0

Это именно то, что мне нужно! К сожалению, у моего defaultdict есть несколько ключей, которые не являются JSON-сериализуемыми без пользовательского кодировщика (ключи - это кортежи, а не мой выбор, только моя проблема) – Kasapo

12

Если defaultdict рекурсивно определяется, например:

from collections import defaultdict 
recurddict = lambda: defaultdict(recurddict) 
data = recurddict() 
data["hello"] = "world" 
data["good"]["day"] = True 

еще другой простой способ конвертировать defaultdict обратно в dict - использовать json модуль

import json 
data = json.loads(json.dumps(data)) 

и, конечно же, значения, содержащиеся в вашем defaultdict, должны быть ограничены типами данных, поддерживаемых json, но это не должно быть проблемой, если вы не намерены хранить классы или функции в dict.

+0

Хорошо, слишком плохо, что мои данные не будут сериализованы в JSON: * ( – Kasapo