2014-01-18 3 views
-1

Что такое pythonic способ обратить вспять defaultdict(list)?Что такое pythonic способ изменить defaultdict (list)?

Я мог выполнять итерацию через defaultdict и создание нового defaultdict. Есть ли другой способ? Является ли это pythonic:

>>> from collections import defaultdict 
>>> x = defaultdict(list) 
>>> y = [[1,2,3,4],[3,4,5,6]] 
>>> z= ['a','b'] 
>>> for i,j in zip(y,z): 
...  x[j] = i 
... 
>>> x 
defaultdict(<type 'list'>, {'a': [1, 2, 3, 4], 'b': [3, 4, 5, 6]}) 
>>> x2 = defaultdict(list) 
>>> for k,v in x.items(): 
...  for i in v: 
...    x2[i].append(k) 
... 
>>> x2 
defaultdict(<type 'list'>, {1: ['a'], 2: ['a'], 3: ['a','b'], 4: ['a','b'], 5: ['b'], 6: ['b']}) 
+0

Непонятно, зачем здесь нужен defaultdict. – bernie

+0

оригинал по умолчанию имеет уникальный идентификатор для тех же вещей с другим именем. Но чтобы искать идентификатор, используя одно из имен, я должен каждый раз делать значение для поиска ключей, поэтому использование обратного defaultdict оптимизирует мой код. – alvas

+3

Не следует выводить для 'x'' defaultdict (, {'a': [1, 2, 3, 4], 'b': [3, 4, 5, 6]}) '? Не знаю, откуда взялась часть «7, 8» данного выхода. –

ответ

2

Я считаю, что лучший способ это просто цикл, как вы делали:

target = defaultdict(list) 
for key, values in original.items(): 
    for value in values: 
     target[value].append(key) 

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

for key, values in original.items(): 
    target.update(zip(values, [key] * len(values))) 

Или с помощью itertools.repeat:

import itertools as it 

for key, values in original.items(): 
    target.update(zip(values, it.repeat(key))) 

Однако эти последние решения работают только в простом случае, когда значения в разных списках различны.


Помните, что у pythonic нет определенного значения. Я «d рассмотреть Python решение, которое:

  1. Читаемые
  2. Правильно использовать функции языка
  3. Правильно использовать встроенные модули/стандартную библиотеку
  4. Эффективное

И точки в порядке важности. Эффективность является последней, потому что это чаще всего подразумевается в пунктах 2 и 3.

1

Является ли это более пифоническим или просто более загадочным?

map(lambda (i, k): x2[i].append(k), [(i, k) for i in v for k, v in x.items()]) 

Следующий вариант необходим для Python 3 и менее ясно:

map(lambda i_k: x2[i_k[0]].append(i_k[1]), [(i, k) for i in v for k, v in x.items()]) 

Дать это, я пришел к выводу, что это, вероятно, о наименее вещий способ сделать это. Но, возможно, образование; это было для меня.

Редактировать: Не делайте этого.

+0

lolz, конечно же загадочный, но да, образовательный =) – alvas

+0

Использование генератора и петли неверно. – thefourtheye

+0

Использование функции, которая имеет побочные эффекты, в 'map', определенно, не является pythonic, я думаю :) – thefourtheye