2012-01-11 67 views
3

我有标准名称交换键和值嵌套价值的物品

standard = ["Richard","Robert","Nicolas"] 

列表和别名的字典(在这种情况下昵称)

aliases = {standard[0]:["Richard","Rick","Dick","Rich"], 
      standard[1]:["Robert","Roberto","Bob"], 
      standard[2]:["Nicolas","Nick","Nic"]} 

我想打一个新的字典我可以把任何别名的名称作为一个键,它会返回标准名称AKA交换密钥和值

我到目前为止唯一的猜测是这个

t = {} 
aliases = [t.update(zip(v,[k]*len(v))) for k,v in aliases.items()] 
aliases = t 

是否有一个整洁或更可读的方式来做到这一点(ID宁愿没有临时字典吨)。

+1

列表理解,才应使用。在你的代码中,列表由'None'值组成,显然是无用的。它使更多可读代码将这种列表理解转换为简单的for循环。 – 2012-01-11 16:51:32

回答

5

我认为这将是更具可读性:

rev_aliases = {} 
for name, nick_list in aliases.iteritems(): 
    for nick in nick_list: 
     rev_aliases[nick] = name 

如果你喜欢某种形式的发电机表达的,你可以使用这些:

的Python> = 2.7:

rev_aliases = {nick: name 
       for name, nick_list in aliases.viewitems() 
       for nick in nick_list} 

的Python < 2.7:

rev_aliases = dict((nick, name) 
        for name, nick_list in aliases.iteritems() 
        for nick in nick_list) 
+1

我认为循环是最可读的。发电机就是我想要调制的东西。谢谢你的回答! – 2012-01-11 17:40:27

1
>>> standard = ["Richard","Robert","Nicolas"] 
>>> aliases = {standard[0]:["Richard","Rick","Dick","Rich"], 
      standard[1]:["Robert","Roberto","Bob"] , 
      standard[2]:["Nicolas","Nick","Nic"] } 
>>> def name(nickname): 
     return [n for n in aliases if nickname in aliases[n]] 

>>> name('Bob') 
['Robert'] 
>>> 

列表解析非常棒。

+0

只是公正的警告,'name()'会迭代所有'aliases',这将比在SvenMarnach的代码中进行字典访问慢得多。 – AdamKG 2012-01-11 16:52:50

+1

的确如此,但有机会出现两个昵称(“Chris” - >“Christopher”,“Christine”,“Willy” - >“Bill”,“William”),它不会全部返回价值。尽管修改他的方法来处理这个问题我认为很简单,但无论如何 – TyrantWave 2012-01-11 16:55:34

1

dict((nick, name) for name, nicks in aliases.iteritems() for nick in nicks)

0

一个有趣的方式滥用itertools:如果你确实需要的资源列表

>>> from itertools import izip, repeat, chain 
>>> dict(chain.from_iterable(
     izip(iter(b), repeat(a, len(b))) 
     for a, b in aliases.iteritems())) 
{'Nicolas': 'Nicolas', 
'Richard': 'Richard', 
'Nic': 'Nicolas', 
'Robert': 'Robert', 
'Dick': 'Richard', 
'Roberto': 'Robert', 
'Nick': 'Nicolas', 
'Rick': 'Richard', 
'Rich': 'Richard', 
'Bob': 'Robert'}