映射到嵌套在字典中的列表上

时间:2018-11-23 13:10:44

标签: python dictionary list-comprehension dictionary-comprehension

数据

我很好奇我是否可以转换以下数据

old_data = {
  "key0": [obj0, obj1],
  "key1": [obj2, obj3]
}

data = {
  "key0": [obj0.id, obj1.id],
  "key1": [obj2.id, obj3.id]
}

使用字典理解。

因此,基本上只是将这些列表对象替换为对象本身的单个属性。所有对象都来自同一类型,因此肯定具有id属性。

词典理解

我想出了以下无效的解决方案:

data = {
  key: [obj.id]
  for key, obj_list in old_data.items()
  for obj in obj_list
}

问题

由于以下这一行,结果字典仅包含具有一个值(被迭代的最后一个值)的列表:

key: [obj.id]

每次仅创建一个带有一个值的新列表。

因此,我不想创建新列表,而是想append将新的obj_id添加到现有列表中,但是我不知道如何。 我认为它一定看起来像这样:

key: data[key].append(obj.id)

但是显然,这也行不通,因为尚未分配data,即使分配了:由于列表从未初始化,所以无法附加第一个obj.id

(我正在使用Python 3.7)

2 个答案:

答案 0 :(得分:1)

功能方法

这不是一个非常Python化的方法,但是仍然很有趣:

from functools import partial
from operator import attrgetter

old_data = {
  "key0": [obj0, obj1],
  "key1": [obj2, obj3]
}

data = dict(zip(old_data, map(list, map(partial(map, attrgetter('id')), old_data.values()))))

答案 1 :(得分:0)

列表理解

所以我找到了使用列表理解的解决方案:

data = {
  key: [obj.id for obj in obj_list]
  for key, obj_list in old_data.items()      
}

只需将循环(for obj in obj_list)移至列表理解范围内即可。

这也解决了以下问题:对于第一个obj,不存在任何列表;此外,其他obj也不需要append方法或类似方法。