Cosa non mi piace dare risposte pronte - ma credo che ci sarebbe voluto molto più tempo per spiegare in inglese -
L'idea di base di prendere oggetti il modo NumPy non è quello di personalizzare il metodo __getitem__
- virgola i valori separati sono presentati al metodo come tuple: tu li usi semplicemente i valori nella tupla come indici ai dizionari nidificati in sequenza.
Oltre a ciò, Python reso facile per creare equivalentes dict completamente funzionale con le classi collections.abc: se si implementa un set minimo di metodi quando inhetiring da collections[.abc].MutableMapping
, tutti i comportamenti dizionario è emulato - (__getitem__, __setitem__, __delitem__, __iter__, __len__
) - Quindi, è solo una questione di iterare correttamente attraverso i componenti chiave e creare nuovi dizionari vuoti per memorizzare i valori necessari.
try:
from collections import MutableMapping
except ImportError:
# Python3 compatible import
from collections.abc import MutableMapping
class NestedDict(MutableMapping):
def __init__(self, *args, **kw):
self.data = dict(*args, **kw)
def get_last_key_levels(self, key, create=False):
if not isinstance(key, tuple):
key = (key,)
current_data = self.data
for subkey in key:
previous = current_data
current_data = current_data[subkey] if not create else current_data.setdefault(subkey, {})
return previous, current_data, subkey
def __getitem__(self, key):
previous, current_data, lastkey = self.get_last_key_levels(key)
return current_data
def __setitem__(self, key, value):
previous, current_data, lastkey = self.get_last_key_levels(key, True)
previous[lastkey] = value
def __delitem__(self, key):
previous, current_data, lastkey = self.get_last_key_levels(key)
del previous[lastkey]
def __iter__(self):
return iter(self.data)
def __len__(self):
return len(self.data)
def __repr__(self):
return "NestedDict({})".format(repr(self.data))
e sei a posto per andare:
>>> from nesteddict import NestedDict
>>> x = NestedDict(a={})
NestedDict({'a': {}})
>>> x["a", "b"] = 10
>>> x
NestedDict({'a': {'b': 10}})
>>> x["a", "c", "e"] = 25
>>> x
NestedDict({'a': {'c': {'e': 25}, 'b': 10}})
>>> x["a", "c", "e"]
25
>>>
Si prega di notare che questa è un'implementazione di alto livello, che sarà solo di lavoro, ma si avrà nessun posto vicino al livello di ottimizzazione si ottiene su NumPy con questo - al contrario. Se devi eseguire operazioni rapide sui dati in questi oggetti, potresti forse controllare "cython" - o ricorrere alla tua idea di trasporre i tasti dict su tasti nuemric e usare NumPy (quell'idea potrebbe ancora raccogliere alcune idee da questa risposta)
Hai davvero bisogno che i dati vengano archiviati in una struttura nidificata? Potresti semplicemente usare un dict le cui chiavi sono le tuple. – BrenBarn
@BrenBarn che potrebbe usare _a sacco_della memoria – 0x539
si può sempre creare una classe contenitore che sovraccarichi '__getitem__' per fare questo, al punto di non essere in grado di usare tuple come indici nei dices nidificati – 0x539