Python отображение "многие-к-одному" (создание классов эквивалентности)
у меня есть проект преобразования одной базы данных в другую. Один из исходных столбцов базы данных определяет категорию строки. Этот столбец должен быть сопоставлен с новой категорией в новой базе данных.
например, предположим, что исходные категории:parrot, spam, cheese_shop, Cleese, Gilliam, Palin
теперь это немного многословно для меня, и я хочу, чтобы эти строки классифицировались как sketch, actor
- то есть определить все эскизы и всех актеров как две эквивалентности занятия.
>>> 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'}
это довольно неудобно - я бы предпочел иметь что-то вроде:
monty={ ('parrot','spam','cheese_shop'): 'sketch',
('Cleese', 'Gilliam', 'Palin') : 'actors'}
но это, конечно, задает весь кортеж в качестве ключа:
>>> monty['parrot']
Traceback (most recent call last):
File "<pyshell#29>", line 1, in <module>
monty['parrot']
KeyError: 'parrot'
есть идеи, как создать элегантный словарь "многие к одному" в Python?
спасибо,
Адам
4 ответов
мне кажется, что у вас есть две проблемы. Во-первых, как вы выражаете свое отображение изначально, то есть как вы вводите отображение в свой new_mapping.py файл. Во-вторых, как работает отображение в процессе повторного отображения. Нет никаких причин для того, чтобы эти два представления были одинаковыми.
начните с отображения вам нравится:
monty = {
('parrot','spam','cheese_shop'): 'sketch',
('Cleese', 'Gilliam', 'Palin') : 'actors',
}
затем преобразуйте его в нужное вам отображение:
working_monty = {}
for k, v in monty.items():
for key in k:
working_monty[key] = v
производство:
{'Gilliam': 'actors', 'Cleese': 'actors', 'parrot': 'sketch', 'spam': 'sketch', 'Palin': 'actors', 'cheese_shop': 'sketch'}
затем использовать working_monty
для выполнения работы.
вы можете переопределить индексатор dict, но, возможно, было бы лучше следующее Более простое решение:
>>> 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'
(возможно, вложенный цикл for может быть сжат впечатляющим однострочным, но это работает и читается.)
>>> 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'
но позвольте мне сказать вам, это будет медленнее, чем обычно один к одному словарю.
Если вы хотите иметь несколько ключей, указывающих на одно и то же значение, т. е.
m_dictionary{('k1', 'k2', 'k3', 'k4'):1, ('k5', 'k6'):2}
и получить к ним доступ как,
`print(m_dictionary['k1'])` ==> `1`.
проверьте этот модуль python multi dictionary multi_key_dict
. Установите и импортируйте его.
https://pypi.python.org/pypi/multi_key_dict