2016-04-29 11 views
12

Ich habe einen defaultdict die wie folgt aussieht:Hinzufügen von Tasten defaultdict (dict)

my_dict = defaultdict(dict) 

die auszudrucken wird:

defaultdict(<class 'dict'>, {}) 

Ich habe auch zwei Listen, die wie folgt aussehen:

list1 = ["W", "IY", "W"] 
list2 = ["w", "ee", "w"] 

ich möchte einen Standard-dict erstellen, die wie folgt aussieht:

die Liste1 in einem Wörterbuch als Schlüssel, mit den Schlüsseln als nächste Liste mit einem separaten Wörterbuch, zählen die Instanzen von Liste2 als Werte.

Bisher habe ich dies:

from collections import defaultdict 

d = defaultdict(dict) 

list1 = ["W", "IY", "W"] 
list2 = ["w", "ee", "w"] 

for char in list1: 
    d[char] += 1 

Ich weiß, dass dies nicht richtig ist, als defaultdict (dict) kann nicht auf diese Weise behandelt werden. Gibt es einen Weg, wie ich das machen könnte? Jede Hilfe würde sehr geschätzt werden :)

+0

Sind die Listen immer die gleiche Länge, und sind alle in list1 Groß- und in list2 Klein? – schwobaseggl

+0

Yesh sie werden immer dieselbe Länge haben. list1 entspricht Phonemen und Liste 2 entspricht Graphemen. Ich versuche, sie zusammen zu bringen. – RoadRunner

Antwort

3

EDITED basierend auf dem Kommentar zu meiner ursprünglichen Antwort.

Sie benötigen eine Zuordnung aller möglichen Phoneme zu allen möglichen Schreibweisen (Grapheme).

phonemes = {TH : [th], O : [o], OH : [oh, oo]} 

for char in set(list1): 
    if char not in d: 
     d[char] = {char.lower() : {phone : list2.count(phone) for phone in phonemes[char]}} 
+1

Wenn Ihre Listen wirklich groß sind, können Sie eine Überprüfung hinzufügen, um zu sehen, ob char bereits in d ist. – aberger

+0

Okay danke @aberger. Mein Problem ist das, wenn ich Listen wie list1 = ["O", "UH", "O"], Liste 2 = ["o", "oo", "o"] habe. Wo ich möchte, dass das "UH" immer noch mit dem "oo" übereinstimmt, weil ich ähnliche Sounds zusammenpasse. Wie kann ich das tun, ohne die .lower() Methode zu benutzen? – RoadRunner

+0

yeah bearbeitet es oben sorry @aberger. – RoadRunner

6

Hier ist eine Lösung mit collections.Counter.

import collections 
d = collections.defaultdict(collections.Counter) 

list1 = ["O", "TH", "O", "O"] 
list2 = ["o", "th", "o", "o1"] 

for key, value in zip(list1, list2): 
    d[key].update([value]) 

>>> d 
defaultdict(<class 'collections.Counter'>, {'TH': Counter({'th': 1}), 'O': Counter({'o': 2, 'o1': 1})}) 
>>> 

Während dies nicht unbedingt Ihre Anforderungen folgen, collections.Counter erbt von dict so hat er alle dict ‚s Attribute

+0

Danke Mann für die Antwort :) – RoadRunner

3

Sie können auch eine verschachtelte defaultdict und zip wie so verwenden:

d = defaultdict(lambda: defaultdict(int)) 
for k, v in zip(list1, list2): 
    d[k][v] += 1 
# d['TH']['th']: 1 
# d['O']['o']: 2 

oder, wenn Sie Ihre Datenstruktur halten:

d = defaultdict(dict) 
for k, v in zip(list1, list2): 
    d[k][v] = d[k].get(v, 0) + 1 
    # use dict.get(key, default=None) and specify an appropriate default value (0) 

Mit dict.get(key, default=None) können Sie Schlüssel-Werte eines gemeinsamen dict viel wie die ein Standarddict zugreifen, jedoch ist die Aktualisierung ein wenig klobiger.

+0

Vielen Dank für die Antwort :) – RoadRunner

2

die etwas andere Art an einer Lösung:

import collections 

phonemes = ["W", "IY", "O", "W", "O"] 
graphemes = ["w", "ee", "o", "w", "oh"] 

# count all the (phoneme, grapheme) pairs 
counter = collections.Counter(zip(phonemes, graphemes)) 

# convert to desired data structure 
d = collections.defaultdict(dict) 
for (phoneme, grapheme), count in counter.items(): 
    d[phoneme][grapheme] = count 

print(d) 

druckt:

defaultdict(<class 'dict'>, {'W': {'w': 2}, 'O': {'oh': 1, 'o': 1}, 'IY': {'ee': 1}}) 
+0

Vielen Dank für die Antwort! :) – RoadRunner

Verwandte Themen