【问题标题】:Update list of dictionaries based on another list of dictionaries根据另一个字典列表更新字典列表
【发布时间】:2013-02-07 19:26:18
【问题描述】:

我有两个字典列表,一个是项目标识符列表,另一个是已完成项目标识符的列表。我希望根据已完成列表中的存在向项目标识符列表中添加一个键。

当前代码

>>> projects = [{'id': 1}, {'id': 2}, {'id': 3}]
>>> completes = [{'id': 1}, {'id': 2}]
>>> for complete in completes:
...     for project in projects:
...         if project["id"] == complete["id"]:
...             project["complete"] = 1
...         else:
...             project["complete"] = 0
...
>>> print projects
[{'id': 1, 'complete': 0}, {'id': 2, 'complete': 1}, {'id': 3, 'complete': 0}]

预期输出

[{'id': 1, 'complete': 1}, {'id': 2, 'complete': 1}, {'id': 3, 'complete': 0}]

一旦项目被标记为完成,我该如何跳出嵌套循环?我应该考虑另一种方法而不是使用嵌套循环吗?

【问题讨论】:

  • 你为什么不做一个项目字典,其中键是id,值可以是你正在使用的信息字典。
  • @GWW 我正在使用输出将 csv 文件作为输入写入 ETL 过程,并希望将列标题保留在字典中。我想我可以按照你的建议创建一个单独的标题和值列表。
  • 如果您正在处理大量条目,它会带来不错的性能提升,否则可能不值得努力。

标签: python python-2.7


【解决方案1】:

编辑 - 已修复(感谢 @sotapme)

为什么不这样:

cids = [c['id'] for c in completes]
for project in projects:
    project["complete"] = project["id"] in cids

这会将project["complete"] 设置为TrueFalse,我建议这样更好。如果你真的需要10,那么:

    project["complete"] = int(project["id"] in cids)

【讨论】:

  • 这对我使用 OP 的数据不起作用。 pastiebin.com/?page=p&id=511401d343247
  • @sotapme。感谢您的编辑建议以及我的解决方案中的美感。不幸的是,我拒绝它,因为我更喜欢在循环之外生成列表。它不会改变并且再生它不利于性能(功能胜于美观)。同样在您建议[i for c in completes for i in c.values()] 的地方,我更喜欢更简单的等效项(在这种情况下等效,如果添加更多键,您的版本可能是错误的)[c['id'] for c in completes]
  • 没关系。我只是想恢复一些原本的优雅。都很好。现在它的行数增加了 50% :D
【解决方案2】:

我无法发表评论,但 jimhark 说的很好,除了我认为你需要说类似的话

for project in projects:
    project['complete'] = project['id'] in (complete['id'] for complete in completes)

编辑:此后他将答案更改为正确

【讨论】:

  • 谢谢。是的,正如@sotapme 指出的那样,我跳过了一步,但我现在已经修好了。
  • 另外,我认为将 id 列表生成拉出循环是值得的。
  • 我也是 - 我只是尽可能少地更改您的原始代码:)
【解决方案3】:

如果您将它们存储为由 id 键入的 dicts 的 dict 与 dicts 数组相比,它会变得容易得多(在我看来):

projects = [{'id': 1}, {'id': 2}, {'id': 3}]
completes = [{'id': 1}, {'id': 2}]

projects_dict = {}
for p in projects:
    projects_dict[p['id']] = p

completes_dict = {}
for c in completes:
    completes_dict[c['id']] = c

for k in projects_dict.keys():
    projects_dict[k]['complete'] = int(k in completes_dict)

当然,不要循环遍历完成,只需在创建“完成”数组的任何位置添加“完成”键即可。

【讨论】:

  • 由于您的 CSV 输出最终需要一个字典数组,因此只需使用 .values() 再次获取您需要的字典数组。
猜你喜欢
  • 2019-02-18
  • 2018-04-30
  • 2022-01-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-06
  • 1970-01-01
相关资源
最近更新 更多