【问题标题】:Create a dict from two existing dicts从两个现有的字典创建一个字典
【发布时间】:2017-04-14 00:06:06
【问题描述】:

我有两个以集合为值的字典。

Dct1 = {'a':[1, 2, 3], 'b':[4, 5, 6, 7], 'c':[8, 9, 10], 'd':[11, 12, 13, 14]}
Dct2 = {'TypeZ':['a', 'b'], 'TypeX':['c', 'd']}

我想创建另一个字典: 1. 遍历 Dct1 中的值的项 2.检查item的value的key是否是Dct2的values中的item 3.将dct2的key作为新dct的key,将dict 1中的值对应项作为新dict的设定值

Dct3 = {'TypeZ':[1, 2, 3, 4, 5, 6, 7], 'TypeX':[8, 9, 10, 11, 12, 13, 14]}

我还想避免在 Dct3 的值中出现重复。

这是我目前正在努力处理的代码的 sn-p(其他 dicts 已经成功构建):

RateByType = {}

for key, item in RoRaDct.items():
    for i, j in TpRtDct.items():
        for x in item:
            for y in j:
                if key == y:
                    RateByType[i].add(item)

但它正在产生一个关键错误。我试过使用 defaultdict(set) 但得到一个 TypeError: unhashable type: set。后者是我用来构建前两个字典的方法。

【问题讨论】:

  • 您说这些值是集合,但您的代码将它们描述为列表(并且您讨论了重复数据删除)。值是set 类型还是list 类型的值?
  • 您在 Dct2 声明中的 TypeX 之后缺少 '
  • 为什么Dct3['TypeX'] 包含11

标签: python dictionary collections


【解决方案1】:

Dct2 的键创建一个集合,然后为Dct3 创建一个defaultdict,循环Dct2 的键及其对应的值:

import collections
Dct1 = {'a':[1,2,3],'b':[4,5,6,7],'c':[8,9,10],'d':[12,12,13,14]}
Dct2 = {'TypeZ':['a','b'],'TypeX':['c','d']}
s = set(Dct2)
d = collections.defaultdict(list)
for key in Dct2:
    for k in Dct2[key]:
        d[key].extend(Dct1[k])

结果:

>>> import pprint
>>> pprint.pprint(d)
{'TypeX': [8, 9, 10, 12, 12, 13, 14],
 'TypeZ': [1, 2, 3, 4, 5, 6, 7]}

【讨论】:

  • 再次感谢。它工作得很好。无论如何要排除某些项目被添加到dict 3中的值?说 exclude = ('c','e') 并在 Dct2[key] 中的 for k 之后插入条件“如果 k 不在排除中:”?
【解决方案2】:
Dct3 = {k: set.union(*map(lambda x: set(Dct1.get(x, [])), v)) for k, v in Dct2.items()}

对于Dct2 中的每个键值对,我们将键映射到集合的并集,这些集合由Dct1 中的键值的成员元素映射到。

编辑:解释

{k: v for k, v in Dct2.items()}

是一个dictionary comprehension,它重新创建了Dct2

set.union(*map(lambda x: set(Dct1.get(x, [])), v))

是我们用来构建系列的东西,但让我们从内到外看看它。

Dct1.get(x, [])

尝试访问Dct1[x] 并返回它。如果dict没有键x,则返回一个空列表[]

set(Dct1.get(x, []))

获取上面Dct1.get 的结果并将其转换为一个集合。

lambda x: set(Dct1.get(x, []))

定义一个匿名函数(即它没有名字)。该函数只接受输入 x 并使用它来评估表达式 set(Dct1.get(x, []))

map(lambda x: set(Dct1.get(x, [])), v)

map 是一个函数,它接受另一个函数(在本例中是我们的 lambda 函数)和一个可迭代对象(如列表),然后生成一个可迭代对象,将该函数应用于输入可迭代对象的每个元素。

*map(lambda x: set(Dct1.get(x, [])), v)

此上下文中的* 运算符用于解压缩可迭代对象。所以它需要像[1, 2, 3] 这样的可迭代对象并将add(*[1, 2, 3]) 转换为add(1, 2, 3)

 set.union(*map(lambda x: set(Dct1.get(x, [])), v))

set.union 是一个函数,它接受多个集合并计算它们的并集,基本上将它们加在一起。

【讨论】:

  • 这个答案给我留下了深刻的印象,但我不得不承认这超出了我的想象。并不是说它更不正确。谢谢。
  • @ShaunO 如果你愿意,我可以写一篇更详细的文章来解释这里发生了什么。我在这里使用了一些函数式编程工具,一旦你将注意力集中在这些工具上,它们就会非常强大。
  • 我很想能够把我的头绕在它周围。如果您真的不介意,我会完全了解它背后的逻辑。
猜你喜欢
  • 2019-11-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多