Як я можу конвертувати вирок за замовчуванням
number_to_letter
defaultdict(<class 'list'>, {'2': ['a'], '3': ['b'], '1': ['b', 'a']})
бути загальним диктом?
{'2': ['a'], '3': ['b'], '1': ['b', 'a']}
Як я можу конвертувати вирок за замовчуванням
number_to_letter
defaultdict(<class 'list'>, {'2': ['a'], '3': ['b'], '1': ['b', 'a']})
бути загальним диктом?
{'2': ['a'], '3': ['b'], '1': ['b', 'a']}
Відповіді:
Ви можете просто зателефонувати dict
:
>>> a
defaultdict(<type 'list'>, {'1': ['b', 'a'], '3': ['b'], '2': ['a']})
>>> dict(a)
{'1': ['b', 'a'], '3': ['b'], '2': ['a']}
але пам’ятайте, що дефолт - це дикт:
>>> isinstance(a, dict)
True
просто з дещо іншою поведінкою, оскільки при спробі отримати доступ до ключа, якого немає, - який зазвичай піднімає a KeyError
- default_factory
замість цього викликається:
>>> a.default_factory
<type 'list'>
Це те, що ви бачите, коли print a
з’являється перед тим, як з’явиться сторона даних словника.
Отже, ще одна хитрість, щоб повернути більше диктоподібної поведінки без фактичного створення нового об’єкта, - це скидання 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
але здебільшого це не варте клопоту.
default_factory
? Я просто не маю уявлення про те, що відбувається. Вибачте.
default_factory
- це та функція, яку ви передали, коли зробили, defaultdict
спочатку, наприклад defaultdict(int)
або defaultdict(list)
. Всякий раз, коли ви намагаєтесь знайти ключ у словнику, як a['3']
, наприклад, у звичайному словнику, ви або отримуєте значення, або воно викликає KeyError
виняток (наприклад, помилка, повідомляючи вам, що не вдалося знайти цей ключ). Але в a defaultdict
, натомість вона викликає default_factory
функцію, щоб зробити для вас нове значення за замовчуванням (це "значення за замовчуванням" defaultdict
).
pickle
(для збереження об’єктів python у файл) не може обробляти defaultdict
s за багатьох обставин .
Якщо ваш вирок за замовчуванням визначений рекурсивно, наприклад:
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))
і, звичайно, значення, що містяться у вашому вироку за замовчуванням, повинні бути обмежені підтримуваними json типами даних, але це не повинно бути проблемою, якщо ви не маєте наміру зберігати класи або функції в дикті.
Якщо вам навіть потрібна рекурсивна версія для перетворення рекурсивної defaultdict
в a, 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)
defaultdict(lambda: defaultdict(int))
): {k: dict(v) for k, v in foo.items()}
dict(number_to_letter)