2017-10-06 91 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使用的生成器表达式;其他一切只是处理避免可变变量的尝试。并非所有事情都可以(或可以)简化为简单的一行。

相关问题