2012-01-11 2 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 предпочитает не иметь временного словаря t).

+1

описаний списков должны быть использованы только если вы на самом деле нужен список. В вашем коде список состоит из значений «Нет» и, очевидно, бесполезен. Это делает гораздо более удобочитаемый код для преобразования такого понимания списка в простой цикл. –

ответ

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

Я понял, что петли были бы наиболее читабельными. Генератор - это то, что я пытался придумать. Спасибо за хороший ответ! –

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()' будет перебирать все «псевдонимы», что будет намного медленнее, чем доступ к словарю, как в коде SvenMarnach. – AdamKG

+1

Правда, но по шансу есть два прозвища, которые разрешают одноименное имя («Крис» -> «Кристофер», «Кристина», «Вилли» -> «Билл», «Уильям»), он не вернет всех ценности. Хотя модифицировать его метод для обработки, который был бы тривиальным, я полагаю, так что ни на что – TyrantWave

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'} 
Смежные вопросы