Czy istnieje sposób, aby defaultdict był również domyślny dla defaultdict? (tj. rekurencyjny słownik default z poziomu nieskończonego?)
Chcę móc:
x = defaultdict(...stuff...)
x[0][1][0]
{}
Więc mogę to zrobić x = defaultdict(defaultdict)
, ale to tylko drugi poziom:
x[0]
{}
x[0][0]
KeyError: 0
Istnieją przepisy, które mogą to zrobić. Ale czy można to zrobić po prostu używając zwykłych argumentów defaultdict?
Zauważ, że jest to pytanie, jak wykonać rekurencyjny defaultdict na nieskończonym poziomie, więc różni się od Python: defaultdict of defaultdict? , czyli jak zrobić dwupoziomowy defaultdict.
Prawdopodobnie skończę po prostu używając wzoru wiązki , ale kiedy zdałem sobie sprawę, że nie wiem, jak to zrobić, zainteresowało mnie to.
python
recursion
defaultdict
Corley Brigman
źródło
źródło
Odpowiedzi:
Dla dowolnej liczby poziomów:
Oczywiście można to również zrobić z lambdą, ale uważam, że lambdy są mniej czytelne. W każdym razie wyglądałoby to tak:
źródło
lambda
, nie zadziała.Inne odpowiedzi tutaj mówią ci, jak stworzyć,
defaultdict
który zawiera „nieskończenie wiele”defaultdict
, ale nie odpowiadają one temu, co moim zdaniem mogło być twoją początkową potrzebą, która polegała na po prostu posiadaniu domyślnego słowa o dwóch głębokościach.Być może szukałeś:
Powody, dla których możesz preferować tę konstrukcję, to:
defaultdict
może być czymś innym niż słownik, np.:defaultdict(lambda: defaultdict(list))
Lubdefaultdict(lambda: defaultdict(set))
źródło
lambda
formularz jest poprawny - ponieważdefaultdict(something)
zwraca obiekt podobny do słownika, aledefaultdict
oczekuje wywołania! Dziękuję Ci!dict(result)
Jest na to sprytna sztuczka:
Następnie możesz utworzyć swój plik
x
zx = tree()
.źródło
Podobne do rozwiązania BrenBarna, ale nie zawiera
tree
dwukrotnie nazwy zmiennej , więc działa nawet po zmianach w słowniku zmiennych:Następnie możesz utworzyć każdy nowy
x
zx = tree()
.W przypadku
def
wersji możemy użyć zakresu zamknięcia funkcji, aby zabezpieczyć strukturę danych przed błędem, w którym istniejące instancje przestają działać, jeślitree
nazwa zostanie ponownie powiązana. To wygląda tak:źródło
Proponowałbym również implementację w stylu OOP, która obsługuje nieskończone zagnieżdżanie, a także odpowiednio sformatowaną
repr
.Stosowanie:
źródło
*args
i,**kwargs
które pozwala mu działać jak thedefaultdict
, a mianowicie tworzyć dyktando z argumentami słów kluczowych. Jest to przydatne przy przechodzeniuNestedDefaultDict
dojson.load
tutaj jest rekurencyjna funkcja do konwersji rekurencyjnego domyślnego dyktu na normalny dykt
źródło
Oparłem to na odpowiedzi Andrew tutaj. Jeśli chcesz załadować dane z json lub istniejącego dyktu do domyślnego narzędzia nester, zobacz ten przykład:
https://gist.github.com/nucklehead/2d29628bb49115f3c30e78c071207775
źródło