2013-06-17 7 views
6

Ich wollte wissen, ob die Funktionalität, die ich in Python implementieren möchte, möglich ist.Mehrere Ebenen von Schlüsseln und Werten in Python

Ich habe einen globalen Hash namens Creatures. Kreaturen enthalten Sub-Hashes genannt Säugetiere, Amphibien, Vögel, Insekten.

Säugetiere haben sub-Hashes genannt Wale, Elefanten. Amphibien haben Sub-Hashes genannt Frösche, Larven. Vögel haben Unter-Hashes genannt Eagle, Sittich. Insekten haben Sub-Hashes genannt Libelle, Mücke.

Wieder haben Eagles Sub-Hashes männlich, weiblich genannt.

Ich zähle die Frequenzen aller dieser Kreaturen aus einer Textdatei. Zum Beispiel, wenn die Datei im unteren Format ist:

Birds Eagle Female 
Mammals whales Male 
Birds Eagle Female 

I should output Creatures[Birds[Eagle[Female]]] = 2 
       Creatures[mammals[Whales[Male]]] = 1 

Ist es in Python möglich? Wie kann es gemacht werden? Ich bin sehr neu in Python und bitte helfen wird sehr geschätzt. Ich bin mit Wörterbüchern nur bis zu einem Niveau vertraut, d.h. Schlüssel-> Wert. Aber hier gibt es mehrere Schlüssel und mehrere Werte. Ich bin mir nicht sicher, wie ich damit verfahren soll. Ich benutze Python 2.6. Danke im Adventure! obwohl

+1

Sollte es für beliebige Verschachtelungsebene ermöglichen? – J0HN

+0

Sie müssen nur "zählen" oder erwarten Sie mehr Verarbeitung Ihrer Daten? –

+0

@ J0HN Ja, Sylvain: Graf wird gut beginnen, später kann ich für mehr Verarbeitung versuchen. –

Antwort

2

Wenn Sie nur „count“ Dinge haben - und die Datendatei unter der Annahme, enthält alle erforderlichen Grad an „Hashes“ - das ist der Trick tun:

import collections 

result = collections.defaultdict(int) 

with open("beast","rt") as f: 
    for line in f: 
     hashes = line.split() 
     key = '-'.join(hashes) 
     result[key] += 1 

print result 

das Ergebnis produzieren:
defaultdict(<type 'int'>, {'Mammals-whales-Male': 1, 'Birds-Eagle-Female': 2})

Wenn Sie verschachtelten Wörterbuch benötigen - Nachbearbeitung dieses Ergebnis ist immer noch möglich ...

17

Der Wert zu einem Schlüssel in einem Wörterbuch zugewiesen wurde, kann sich

creatures = dict() 
creatures['birds'] = dict() 
creatures['birds']['eagle'] = dict() 
creatures['birds']['eagle']['female'] = 0 
creatures['birds']['eagle']['female'] += 1 

Sie benötigen ein anderes Wörterbuch explizit jedes Wörterbuch erstellen. Im Gegensatz zu Perl erstellt Python nicht automatisch ein Wörterbuch, wenn Sie versuchen, den Wert eines nicht zugewiesenen Schlüssels als solchen zu behandeln.

Es sei denn natürlich, verwenden Sie einen defaultdict:

from collections import defaultdict 
creatures = defaultdict(lambda: defaultdict(lambda: defaultdict(int))) 
creatures['birds']['eagle']['female'] += 1 

Für beliebige Verschachtelungsebenen, können Sie diese rekursive Definition

dd = defaultdict(lambda: dd) 
creatures = dd() 
creatures['birds']['eagle']['female'] = 0 

In diesem Fall verwenden können, müssen Sie explizit initialisieren der ganzzahlige Wert, da ansonsten der Wert creatures['birds']['eagle']['female'] als ein weiterer defaultdict angenommen wird.

+0

Vögel, Tiere, etc .. sind nur Beispiele, keine tatsächlichen Einträge.Eigentlich muss ich aus der Datei lesen und sie automatisch hinzufügen –

1

Nicht elegant, aber die Arbeit:

result = {} 
for line in input_file.split("\n"): 
    curdict = result 
    values = line.split(" ") 
    for item in values[:-1]: 
     if item not in curdict: 
      curdict[item] = {} 
     curdict = curdict[item] 
    last_item = values[-1] 
    if last_item not in curdict: 
     curdict[last_item] = 0 
    curdict[last_item] += 1 

Dies kann wahrscheinlich auf eine sauberere Art und Weise geschrieben werden, aber zumindest funktioniert es und ermöglicht eine beliebige Verschachtelungsebene, es sei denn, Sie haben unterschiedliche Verschachtelungsebenen für dieselbe "Einheit" (z. Birds Eagle Female und Birds Eagle wird nicht funktionieren)

Verwandte Themen