Python多对一映射(创建等价类)

Ada*_*tan 12 python many-to-one equivalence-classes

我有一个将一个数据库转换为另一个数据库的项目 其中一个原始数据库列定义行的类别.此列应映射到新数据库中的新类别.

例如,我们假设原始类别是:parrot, spam, cheese_shop, Cleese, Gilliam, Palin

现在这对我来说有点冗长,而且我希望将这些行分类为sketch, actor- 也就是说,将所有草图和所有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'}
Run Code Online (Sandbox Code Playgroud)

这很尴尬 - 我更喜欢这样的东西:

monty={ ('parrot','spam','cheese_shop'): 'sketch', 
        ('Cleese', 'Gilliam', 'Palin') : 'actors'}
Run Code Online (Sandbox Code Playgroud)

但是,这当然将整个元组设置为关键:

>>> monty['parrot']

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

如何在Python中创建优雅的多对一字典?

谢谢,

亚当

Ned*_*der 12

在我看来,你有两个问题.首先,如何最初表达映射,即如何在new_mapping.py文件中键入映射​​.其次,映射在重映射过程中如何工作.这两种表示没有理由相同.

从您喜欢的映射开始:

monty = { 
    ('parrot','spam','cheese_shop'): 'sketch', 
    ('Cleese', 'Gilliam', 'Palin') : 'actors',
}
Run Code Online (Sandbox Code Playgroud)

然后将其转换为您需要的映射:

working_monty = {}
for k, v in monty.items():
    for key in k:
        working_monty[key] = v
Run Code Online (Sandbox Code Playgroud)

生产:

{'Gilliam': 'actors', 'Cleese': 'actors', 'parrot': 'sketch', 'spam': 'sketch', 'Palin': 'actors', 'cheese_shop': 'sketch'}
Run Code Online (Sandbox Code Playgroud)

然后working_monty用来做这项工作.

  • +1非常感谢.我假设这个工作没有python原生类型; 你认为应该有吗? (2认同)

Vla*_*nko 5

您可以覆盖 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'
Run Code Online (Sandbox Code Playgroud)

(也许嵌套的 for 循环可以压缩成令人印象深刻的单行代码,但这是可行的并且是可读的。)

  • 不适合胆小的人: equiv_dict = dict( sum([[(k, v) for k in ks] for (ks, v) in assoc_list], []) ) (2认同)