Da wir wissen nicht im Voraus, wenn wir ein Wörterbuch oder eine Liste benötigen, dann kombinieren Sie können nicht autovivification mit Listen. Wenn Sie Nosklos Antwort von der verknüpften Frage nicht abarbeiten, fügen Sie dem zugrunde liegenden Wörterbuch "Features" hinzu. Im Grunde nehmen wir eine "Sortierreihenfolge" für Schlüssel an und verwenden sie immer mit den Listenmethoden. Ich habe dies als ein Beispiel getan:
class AutoVivification(dict):
"""Implementation of perl's autovivification feature. Has features from both dicts and lists,
dynamically generates new subitems as needed, and allows for working (somewhat) as a basic type.
"""
def __getitem__(self, item):
if isinstance(item, slice):
d = AutoVivification()
items = sorted(self.iteritems(), reverse=True)
k,v = items.pop(0)
while 1:
if (item.start < k < item.stop):
d[k] = v
elif k > item.stop:
break
if item.step:
for x in range(item.step):
k,v = items.pop(0)
else:
k,v = items.pop(0)
return d
try:
return dict.__getitem__(self, item)
except KeyError:
value = self[item] = type(self)()
return value
def __add__(self, other):
"""If attempting addition, use our length as the 'value'."""
return len(self) + other
def __radd__(self, other):
"""If the other type does not support addition with us, this addition method will be tried."""
return len(self) + other
def append(self, item):
"""Add the item to the dict, giving it a higher integer key than any currently in use."""
largestKey = sorted(self.keys())[-1]
if isinstance(largestKey, str):
self.__setitem__(0, item)
elif isinstance(largestKey, int):
self.__setitem__(largestKey+1, item)
def count(self, item):
"""Count the number of keys with the specified item."""
return sum([1 for x in self.items() if x == item])
def __eq__(self, other):
"""od.__eq__(y) <==> od==y. Comparison to another AV is order-sensitive
while comparison to a regular mapping is order-insensitive. """
if isinstance(other, AutoVivification):
return len(self)==len(other) and self.items() == other.items()
return dict.__eq__(self, other)
def __ne__(self, other):
"""od.__ne__(y) <==> od!=y"""
return not self == other
Dies folgt die grundlegende Autovivifikations-Funktion der dynamischen Generierung selbst für Blindtasten. Es implementiert jedoch auch einige der Methoden listed here. Dies ermöglicht es, wie eine Quasi-Liste/Diktat zu handeln.
Für den Rest der Liste Funktionen, in den aufgeführten Methoden hinzufügen. Ich behandle es als ein Wörterbuch mit den Listenmethoden. Wenn eine Listenmethode aufgerufen wird, nimmt sie eine Annahme über die Reihenfolge der gehaltenen Elemente vor, nämlich, dass Zeichenfolgen niedriger als ganze Zahlen sortiert werden und dass Schlüssel immer in "sortierter" Reihenfolge sind.
Es unterstützt auch das Hinzufügen, als Beispiel für these methods. Das kommt von meinem eigenen Anwendungsfall. Ich musste Elemente aus einem AutoVivified-Wörterbuch hinzufügen, aber wenn es nicht existiert, wird ein neues AutoVivification
-Objekt erstellt und zurückgegeben.Sie haben keine ganze Zahl „Wert“ und so können Sie dies nicht tun:
rp = AutoVivification()
rp['a']['b'] = 3
rp['a']['b'] + rp['q']
, dass der Zweck vereitelt, da ich weiß nicht, ob etwas, was es sein wird, aber ich möchte einen Standard sowieso. Also habe ich die Methoden __add__
und __radd__
hinzugefügt. Sie verwenden das length
des zugrunde liegenden Wörterbuchs als integer
Wert, so ein neu erstelltes AV-Objekt hat einen Wert von Null für die Addition. Wenn ein Schlüssel etwas anderes als ein AV-Objekt enthält, dann erhalten wir die Additionsmethode, wenn diese implementiert ist.
Schöne Lösung. Vielen Dank. – Zhang18
Ein Beispiel von Python mit einer einzigen, offensichtlichen Möglichkeit, etwas zu tun :) – Brian
Tatsächlich erkannte ich, dass diese Antwort nur für 2 Ebenen des Diktats und eine dritte Ebene der Liste funktioniert. Gibt es eine Möglichkeit, levelunabhängig zu sein? dh nachdem ich a deklariert habe, kann ich entweder 'a' (x '), append (' z ')' oder 'a' 'x' '[' y '] [' w '] append (' z ') '? Danke. – Zhang18