2017-10-06 87 views
2

Python字典鍵值有沒有簡單的方法來交換,其中值列表 我的字典類似於以下有沒有簡單的方法來交換,其中值列表

d={1:[1,2,3,4],2:[2,3,4],5:[1,3,6,7]} 

Python字典鍵值我想生成從它的字典像下面

a={1:[1,5],2:[1,2],3:[1,2,5],4:[1,2],6:[5],7:[5]} 

我與反

dict(map(reversed, d.items()) 
測試210

它不會重複,並創建列表中的項鍵返回類型錯誤:unhashable類型:「名單」

我尋找可用的實現這個

+0

聽起來像你想要一個有向圖。 – erip

+0

你關心列表元素的順序嗎? –

+0

不要照顧訂單 – Bamaboy

回答

2

你的方法是行不通的任何內嵌的方法,因爲在這裏,你的目標是構建一個字典:

{[1,2,3,4]: 1, [2,3,4]: 2, [1,3,6,7]: 5}

但由於名單是unhashable,這些不能被用作鍵(進而是不是你打算無論如何要構建什麼)。

你可能會更好使用這一個defaultdict

from collections import defaultdict 

result = defaultdict(list) 
for k, vs in d.items(): 
    for v in vs: 
     result[v].append(k) 

這個opertion後,resultdefaultdict它映射中的值以鍵列表項(一個在香草dict的子類)(即包含該值)。像:

>>> result 
defaultdict(<class 'list'>, {1: [1, 5], 2: [1, 2], 3: [1, 2, 5], 4: [1, 2], 6: [5], 7: [5]}) 

您可選擇使用:

result = dict(result) 

來創建具有這些值的新字典(並因此刪除defaultdict)。

記住:

  • 因爲大多數Python解釋不要命的字典(它絕對不是硬假設你可以),在列表中可能會有所不同元素的順序;和
  • 您的字典列表中的項目d應該是可排列
3

這將工作:

def revdict(d): 
    r = {} 
    for k in d: 
     for v in d[k]: 
      if v not in r: 
       r[v] = [k] 
      else: 
       r[v].append(k) 
    return r 

然後,你可以這樣做:

d={1:[1,2,3,4],2:[2,3,4],5:[1,3,6,7]} 
a = revdict(d) 
print(a) 

如果你想避免檢查新的按鍵,你可以使用一個defaultdict,然後總是追加。

0

這不是真的適合單班輪;你簡單地將其稱爲簡單的逆轉,從而簡化了你需要做的事情。

一個真正的逆轉只會值映射到按鍵代替鍵的值,你可以這樣做(用列表來元組輕微,但必要的更改):

>>> print dict((tuple(d[k]), k) for k in d) 
{(1, 3, 6, 7): 5, (2, 3, 4): 2, (1, 2, 3, 4): 1} 

你需要的是更爲複雜,通常被稱爲字典的轉置。

from operator import itemgetter as ig 
from itertools import groupby 

transposed_dict = dict((k, map(ig(1), v)) 
         for k, v in groupby(
             sorted((nk, k) for k in d for nk in d[k]), 
              key=ig(0))) 

沒有什麼特別簡單的這個年代,雖然在概念上它是不是太糟糕:

  1. (nk, k) for k in d for nk in d[k]創建從字典的擴展的關聯列表,倒置鍵和值。

  2. groupby收集所有與共同的第一元件

  3. (k, map(ig(1), v))收集與共同的第一元件的元組成單個元組元組:(1,1), (1,2) => (1, [1,2])

  4. 來自步驟3的元組用於構建新的字典。

然而,使用簡單的3行for循環(如Willem Van Onsem所示;該循環的實質在於sorted使用的生成器表達式;其他一切只是處理避免可變變量的嘗試。並非所有事情都可以(或可以)簡化爲簡單的一行。

相關問題