Python molti-a-uno mappatura (la creazione di classi di equivalenza)
-
20-09-2019 - |
Domanda
Ho un progetto di conversione di un database a un altro. Una delle colonne del database originale definisce categoria della riga. Questa colonna deve essere associata a una nuova categoria nel nuovo database.
Per esempio, supponiamo che le categorie originali sono: parrot, spam, cheese_shop, Cleese, Gilliam, Palin
Ora che è un po 'prolisso per me, e voglio avere queste righe classificati come sketch, actor
-. Cioè, definire tutti gli schizzi e tutti gli attori come due classi di equivalenza
>>> 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'}
Questo è abbastanza awkward- Io preferirei avere qualcosa di simile:
monty={ ('parrot','spam','cheese_shop'): 'sketch',
('Cleese', 'Gilliam', 'Palin') : 'actors'}
Ma questo, naturalmente, imposta l'intera tupla come chiave:
>>> monty['parrot']
Traceback (most recent call last):
File "<pyshell#29>", line 1, in <module>
monty['parrot']
KeyError: 'parrot'
Tutte le idee su come creare un elegante molti-a-uno dizionario in Python?
Grazie,
Adam
Soluzione
Mi sembra che si hanno due preoccupazioni. In primo luogo, come si fa a esprimere la vostra mappatura in origine, vale a dire, come si fa a digitare la mappatura nel file new_mapping.py. In secondo luogo, come fa il lavoro di mappatura durante il processo di re-mapping. Non c'è ragione di queste due rappresentazioni per essere lo stesso.
Inizia con la mappatura che ti piace:
monty = {
('parrot','spam','cheese_shop'): 'sketch',
('Cleese', 'Gilliam', 'Palin') : 'actors',
}
quindi convertirlo nella mappatura è necessario:
working_monty = {}
for k, v in monty.items():
for key in k:
working_monty[key] = v
produzione:
{'Gilliam': 'actors', 'Cleese': 'actors', 'parrot': 'sketch', 'spam': 'sketch', 'Palin': 'actors', 'cheese_shop': 'sketch'}
quindi utilizzare working_monty
per fare il lavoro.
Altri suggerimenti
Si potrebbe ignorare indicizzatore di dict, ma forse la seguente soluzione più semplice sarebbe meglio:
>>> 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'
(Forse la nidificato ciclo for può essere compresso un impressionante one-liner, ma questo funziona ed è leggibile.)
>>> 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'
Ma lasciate che vi dica, sarà lento rispetto al normale 1-1 dizionario.
Se si desidera avere più chiavi che puntano allo stesso valore, vale a dire
m_dictionary{('k1', 'k2', 'k3', 'k4'):1, ('k5', 'k6'):2}
e accedervi come,
`print(m_dictionary['k1'])` ==> `1`.
Controlla questo multi dizionario Python modulo multi_key_dict
. Installare e importarlo.
https://pypi.python.org/pypi/multi_key_dict