多通映射(创建等价类)

2024-06-12 19:27:58 发布

您现在位置: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创建一个优雅的多对一字典吗


Tags: 项目数据库定义spamshop类别actorparrot
3条回答
>>> 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'

但是让我告诉你,它会比普通的一对一字典慢

您可以覆盖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循环可以压缩成令人印象深刻的一行,但这是可行的,而且可读性强。)

在我看来,你有两个顾虑。首先,您最初是如何表达映射的,也就是说,如何将映射键入新的_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来做这项工作

相关问题 更多 >