2009-12-17 11 views
9

Ich habe ein Projekt zum Konvertieren einer Datenbank in eine andere. Eine der ursprünglichen Datenbankspalten definiert die Kategorie der Zeile. Diese Spalte sollte einer neuen Kategorie in der neuen Datenbank zugeordnet werden.Python-Viele-zu-Eins-Mapping (Erstellen von Äquivalenzklassen)

Zum Beispiel nehmen wir an, die ursprünglichen Kategorien sind: parrot, spam, cheese_shop, Cleese, Gilliam, Palin

Nun, da für mich ein wenig weitschweifig ist, und ich will diese Zeilen als sketch, actor kategorisiert haben - das heißt, definieren alle Skizzen und alle Akteure zwei Äquivalenzklassen.

>>> monty={'parrot':'sketch', 'spam':'sketch', 'cheese_shop':'sketch', 
'Cleese':'actor', 'Gilliam':'actor', 'Palin':'actor'} 
>>> monty 
{'Gilliam': 'actor', 'Cleese': 'actor', 'parrot': 'sketch', 'spam': 'sketch', 
'Palin': 'actor', 'cheese_shop': 'sketch'} 

, die ganz awkward- ist würde ich so etwas wie lieber mit:

monty={ ('parrot','spam','cheese_shop'): 'sketch', 
     ('Cleese', 'Gilliam', 'Palin') : 'actors'} 

Aber dies natürlich setzt die gesamte Tupel als Schlüssel:

>>> monty['parrot'] 

Traceback (most recent call last): 
    File "<pyshell#29>", line 1, in <module> 
    monty['parrot'] 
KeyError: 'parrot' 

Irgendwelche Ideen, wie man Erstellen Sie ein elegantes Viele-zu-Eins-Wörterbuch in Python?

Danke,

Adam

+1

Überprüfen Sie diese elegante [Antwort] (http://StackOverflow.com/a/11105962/355230) auf eine ähnliche Frage. – martineau

Antwort

11

Es scheint mir, dass Sie zwei Bedenken haben. Erstens, wie drücken Sie Ihr Mapping ursprünglich aus, also wie geben Sie das Mapping in Ihre Datei new_mapping.py ein. Zweitens, wie funktioniert das Mapping während des Re-Mapping-Prozesses? Es gibt keinen Grund dafür, dass diese beiden Darstellungen gleich sind.

Beginnen Sie mit der Zuordnung Sie mögen:

monty = { 
    ('parrot','spam','cheese_shop'): 'sketch', 
    ('Cleese', 'Gilliam', 'Palin') : 'actors', 
} 

es dann in das Mapping konvertieren Sie brauchen:

working_monty = {} 
for k, v in monty.items(): 
    for key in k: 
     working_monty[key] = v 

Herstellung:

{'Gilliam': 'actors', 'Cleese': 'actors', 'parrot': 'sketch', 'spam': 'sketch', 'Palin': 'actors', 'cheese_shop': 'sketch'} 

dann working_monty verwenden, um die Arbeit zu tun .

+1

+1 Vielen Dank. Ich nehme an, dass es für diesen Job keinen nativen Python-Typ gibt. Denkst du, dass es einen geben sollte? –

+0

Können wir nicht eine Referenz als Wert im Paar (Schlüssel, Wert) haben, anstatt die tatsächliche Zeichenfolge zu speichern? Da die Nr. Schlüssel sind deutlich größer als die Nr. von Werten würde dies viel Platz sparen. Gibt es eine Möglichkeit, dies zu tun? – ishan3243

1
>>> monty={ ('parrot','spam','cheese_shop'): 'sketch', 
     ('Cleese', 'Gilliam', 'Palin') : 'actors'} 

>>> item=lambda x:[z for y,z in monty.items() if x in y][0] 
>>> 
>>> item("parrot") 
'sketch' 
>>> item("Cleese") 
'actors' 

Aber lassen Sie mich Ihnen sagen, es wird als normal 12.59 Wörterbuch langsam sein.

+0

Langsam, aber auf der Plusseite erfordert keine persistente sekundäre Datenstruktur. Könnte etwas beschleunigt werden, indem man nicht als Lambda geschrieben wird und ein Listenverständnis verwendet. – martineau

4

könnten Sie dict Indexer außer Kraft setzen, aber vielleicht die folgende einfachere Lösung wäre besser: (. Vielleicht ist die verschachtelte kann Schleife einen beeindruckenden Einzeiler werden komprimiert, aber das funktioniert und ist lesbar)

>>> assoc_list = ((('parrot','spam','cheese_shop'), 'sketch'), (('Cleese', 'Gilliam', 'Palin'), 'actors')) 
>>> equiv_dict = dict() 
>>> for keys, value in assoc_list: 
    for key in keys: 
     equiv_dict[key] = value 


>>> equiv_dict['parrot'] 
'sketch' 
>>> equiv_dict['spam'] 
'sketch' 

+1

Nicht für schwache Nerven: equiv_dict = dict (Summe [[(k, v) für k in ks] für (ks, v) in assoc_list], [])) –

0

Wenn Sie auf den gleichen Wert zeigen mehrere Schlüssel haben wollen, das heißt

m_dictionary{('k1', 'k2', 'k3', 'k4'):1, ('k5', 'k6'):2} und greifen Sie wie

`print(m_dictionary['k1'])` ==> `1`. 

prüfen dieses Multi-Wörterbuch Python-Modul multi_key_dict. Installieren und importieren Sie es. https://pypi.python.org/pypi/multi_key_dict