2014-02-02 3 views
0
def invert_dict(d): 
    inv = dict() 
    for key in d: 
     val = d[key] 
     if val not in inv: 
      inv[val] = [key] 
     else: 
      inv[val].append(key) 
return inv 

Это пример из книги Think Python, функции для инвертирования (замены) ключей и значений в словаре. Новые значения (прежние ключи) хранятся в виде списков, поэтому, если перед инвертированием было несколько значений словаря (связанных с разными ключами), то эта функция просто добавляет их в список прежних ключей.Понимание словаря для обмена ключами/значениями в dict с несколькими равными значениями

Пример:

somedict = {'one': 1, 'two': 2, 'doubletwo': 2, 'three': 3} 
invert_dict(somedict) ---> {1: ['one'], 2: ['doubletwo', 'two'], 3: ['three']} 

Мой вопрос, может ли то же самое делается с словарем постижений? Эта функция создает пустой dict , который затем проверяется позже в функции с if/else на наличие значений. В этом случае понимание Дикта должно проверяться. Это возможно и как должен выглядеть синтаксис?

Общий ДИКТ понимание синтаксис для замены значений:

{value:key for key, value in somedict.items()} 

, но если я хочу, чтобы добавить «если» clausule, что это должно выглядеть? if value not in (what)?

Спасибо.

+0

обычно путь сокращения, что 'invert_dict' код использовать' setdefault' или 'defaultdict'. Я не знаю, как написать это в понимании dict, и подозревать, что любые средства для этого будут полностью нечитаемы. – roippi

+0

Возможный дубликат [Добавить в список списков с пониманием dict] (http://stackoverflow.com/questions/11276473/append-to-a-dict-of-lists-with-a-dict-comprehension) – dawg

ответ

1

Вы можете использовать набор на слух побочный эффект:

somedict = {'one': 1, 'two': 2, 'doubletwo': 2, 'three': 3} 

invert_dict={} 
{invert_dict.setdefault(v, []).append(k) for k, v in somedict.items()} 

print invert_dict 
# {1: ['one'], 2: ['doubletwo', 'two'], 3: ['three']} 
2

Я не думаю, что это возможно с простым пониманием dict без использования других функций.

Следующий код использует itertools.groupby для группировки ключей, имеющих одинаковые значения.

>>> import itertools 
>>> {k: [x[1] for x in grp] 
    for k, grp in itertools.groupby(
     sorted((v,k) for k, v in somedict.iteritems()), 
     key=lambda x: x[0]) 
    } 
{1: ['one'], 2: ['doubletwo', 'two'], 3: ['three']}