2010-03-05 11 views
27

Ich verwende derzeit die folgende Methode, um ein mehrdimensionales Wörterbuch in Python zu definieren. Meine Frage ist: Ist das der bevorzugte Weg, mehrdimensionale Diktate zu definieren?Die beste Methode zum Definieren mehrdimensionaler Wörterbücher in Python?

from collections import defaultdict 

def site_struct(): 
    return defaultdict(board_struct) 

def board_struct(): 
    return defaultdict(user_struct) 

def user_struct(): 
    return dict(pageviews=0,username='',comments=0) 

userdict = defaultdict(site_struct) 

die folgende Struktur zu erhalten:

userdict['site1']['board1']['username'] = 'tommy' 

Ich verwende diese auch, wenn ein Schlüssel oder bereits auf 0 gesetzt besteht zu überprüfen, ohne dass ein Benutzerzähler on the fly zu erhöhen. Zum Beispiel:

userdict['site1']['board1']['username']['pageviews'] += 1 
+0

Dieser Code wird den In Python Interpreter nicht ausführen. Dies macht es schwierig zu verstehen, was Sie tun möchten. – krumpelstiltskin

Antwort

43

Tupel sind waschbar. Vermutlich vermisse ich den Punkt, aber warum verwenden Sie kein Standardwörterbuch mit der Konvention, dass die Schlüssel verdreifacht werden? Zum Beispiel:

userdict = {} 
userdict[('site1', 'board1', 'username')] = 'tommy' 
+1

Ich empfehle diesen Ansatz, es sei denn, Sie müssen userdict ['site1'] an eine Funktion übergeben. –

+0

Ich mag diese Idee. Genau dafür sind Tupel wegen ihrer unveränderlichen Natur gut. – jathanism

+2

Dies funktioniert sehr gut, solange Sie nicht alle Board-Einträge unter 'site1' auflisten müssen. –

1

Dies ist eine ziemlich subjektive Frage aus meiner Sicht. Für mich wäre die wirkliche Frage, ab welchem ​​Punkt Sie diese verschachtelte Datenstruktur für Objekte mit Methoden propagieren, die Sie von Änderungen isolieren. Ich habe jedoch dafür bekannt, große Prototyping Namensraum mit der folgenden erstellen:

from collections import defaultdict 

def nesteddict(): 
    return defaultdict(nesteddict) 
+0

Diese Lösung behält die Fähigkeit, über Dimensionen zu iterieren, erstellt jedoch eine Abhängigkeit für nesteddict. – GregB

16

Sie können ein mehrdimensionales Wörterbuch jeglicher Art wie folgt erstellen:

from collections import defaultdict 
from collections import Counter 

def multi_dimensions(n, type): 
    """ Creates an n-dimension dictionary where the n-th dimension is of type 'type' 
    """ 
    if n<=1: 
    return type() 
    return defaultdict(lambda:multi_dimensions(n-1, type)) 

>>> m = multi_dimensions(5, Counter) 
>>> m['d1']['d2']['d3']['d4'] 
Counter() 
+0

Wenn ich das versuche, bekomme ich 'TypeError: Erforderliches Argument 'Name' (Pos 1) nicht gefunden', das auf die Zeile 'return type()' verweist. – hepcat72

+0

Ich habe mein Problem herausgefunden - es ist nur ein Unterschied, wie ich "N-dimensionale" Wörterbücher definiere und wie es oben definiert ist. Z.B. Ein einzelnes Datum wird mit 0 Dimensionen indiziert. Ein einfaches Array wird um 1 Dim indiziert. Die Werte in einem Array von Arrays werden mit 2 Dims indiziert. Und Dicts sind nur Arrays, die durch Strings indiziert werden. Die Werte, die es enthält, sind für mich keine zusätzliche Dimension, obwohl ich sehe, wie man es so sehen kann. Im obigen Beispiel hätte ich es ein 4D-Dict genannt, nicht 5, also funktionierte mein Code nicht, weil ich den Typ erwartete anstatt einer dict @ 1 Dimension, die schüchtern war von dem, was er mir gab. – hepcat72

1

Das ist sehr subjektiv - aber wenn Ihr dict wird mehr als 2-n tief, ich würde zur Erstellung einer Klasse zurückkehren und Methoden/Eigenschaften definieren, um das zu tun, was Sie wollen.

Ich denke, Ihr Endziel wäre, eine "mehrspaltige" Datenstruktur zu erstellen, so dass Sie eine beliebige Anzahl von Attributen für ein bestimmtes Objekt speichern können (in diesem Fall eine Website). Das Erstellen einer Site-Klasse würde das erreichen und dann können Sie Instanzen an einem beliebigen anderen Objekt (Variable) festhalten - mit einigen bekannten Ausnahmen.

Verwandte Themen