Mapeo de varios a uno de Python (creando clases de equivalencia)

Tengo un proyecto de convertir una base de datos a otra. Una de las columnas de la base de datos original define la categoría de la fila. Esta columna debe asignarse a una nueva categoría en la nueva base de datos.

Por ejemplo, asummos que las categorías originales son: parrot, spam, cheese_shop, Cleese, Gilliam, Palin

Ahora eso es un poco detallado para mí, y quiero clasificar estas filas como sketch, actor , es decir, definir todos los bocetos y todos los actores como dos clases de equivalencia.

 >>> 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'} 

Eso es bastante incómodo, preferiría tener algo como:

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

Pero esto, por supuesto, establece la tupla entera como una clave:

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

¿Alguna idea de cómo crear un elegante diccionario de muchos a uno en Python?

Gracias,

Adán

Me parece que tienes dos preocupaciones. Primero, ¿cómo expresa su asignación originalmente, es decir, cómo escribe la asignación en su archivo new_mapping.py? En segundo lugar, ¿cómo funciona el mapeo durante el proceso de re-mapeo? No hay razón para que estas dos representaciones sean iguales.

Comienza con el mapeo que te gusta:

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

entonces conviértalo en el mapeo que necesita:

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

productor:

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

luego use working_monty para hacer el trabajo.

Podría anular el indexador de dict, pero quizás la siguiente solución más simple sería mejor:

 >>> 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' 

(Quizás el bucle nested para se pueda comprimir de una forma impresionante, pero esto funciona y es legible).

 >>> 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' 

Pero déjame decirte que será lento de lo normal un diccionario a otro.

Si desea tener varias claves que apunten al mismo valor, es decir

m_dictionary{('k1', 'k2', 'k3', 'k4'):1, ('k5', 'k6'):2} y acceda a ellos como,

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

Verifique este módulo de diccionario múltiple de python multi_key_dict . Instalarlo e importarlo. https://pypi.python.org/pypi/multi_key_dict