【问题标题】:Efficient way to search a list of dictionaries in Python在 Python 中搜索字典列表的有效方法
【发布时间】:2015-04-02 02:31:03
【问题描述】:

我的当前字典列表如下所示:

  x =[{u'id': 813, u'overlap': 1.0},
      {u'id': 811, u'overlap': 0.002175817439439302},
      {u'id': 812, u'overlap': 0.012271742728263339},
      {u'id': 814, u'overlap': 0.9182077233294997},
      {u'id': 815, u'overlap': 0.8866809411969082},
      {u'id': 117, u'overlap': 0.9173796235219325},
      {u'id': 816, u'overlap': 0.9460961805523018},
      {u'id': 116, u'overlap': 0.2038311249297872},
      {u'id': 817, u'overlap': 0.7302323133830623},
      {u'id': 818, u'overlap': 0.81532953091762},
      {u'id': 819, u'overlap': 0.2817392052504116},
      {u'id': 820, u'overlap': 0.7905202140586483},
      {u'id': 821, u'overlap': 0.8497466449368322},
      {u'id': 822, u'overlap': 0.8503886863531487},
      {u'id': 823, u'overlap': 1.0}]

我想找到例如 id==820 的重叠,即 0.7905202140586483

如何用几行 Python 代码高效而优雅地完成它? (我将循环数百万个这样的数组)。

【问题讨论】:

  • 列表没有这种方式——根据定义,列表是按顺序搜索的,除非您单独维护某种索引。为什么不把它改成字典呢?
  • 我是从 Mongodb 中读到的。我可以轻松地将其转换为以 id 为键、重叠为值的字典吗?
  • 当然可以。我把它留给你一个练习,提示是:dict理解。
  • 如果你给出产生序列的代码的相关部分(我对所涉及的类感兴趣),我们可能会建议一种方法来返回已经被id 索引的序列。 MongoDB 似乎能够做到这一点。
  • 是否有可能多个列表条目具有重叠的键?

标签: python arrays list dictionary


【解决方案1】:

因为每个字典只有两个值(一个“id”和一个“重叠”),我建议您尝试将整个内容转换为一个大字典,然后从那里开始。比如:

x_dict = {entry['id']: entry['overlap'] for entry in x}

然后你可以通过调用 .get() 得到你想要的值:

x_dict.get(id)

【讨论】:

    【解决方案2】:
    x2 = {d["id"]:d["overlap"] for d in x}
    print x2[820]
    

    如 cmets 中所述,使用字典

    或从 id=820 的 mongo 查询(不确定如何直接使用 mongo 几次)

    【讨论】:

      【解决方案3】:

      效率取决于情况。值得注意的是,将其转换为 dict 并非没有成本。如果您使用几乎所有项目,请将其转换为建议的字典。如果您只使用列表中的几个项目,这将更有效率:

      d = {v['id']: v['overlap'] for v in x if v['id'] in (820, 811, 117)}
      

      一项小型测试(包含您问题中的列表)表明,如果您只寻找 2/15 项,这可以减少约 33% 的时间使用。在 15 项中超过 5-6 项时,它不再更快。

      您必须自己测试它如何扩展到更大的列表(您可以为此使用timeit.timeit)。如果您能够创建一个列表而不是的字典,那就去吧。否则,如果这是应用程序中对性能至关重要的部分,请进行一些测试,看看哪种方法最适合您的情况。

      【讨论】:

      • 这太棒了!我实际上最多使用两个项目,这非常有效!
      • 我不知道你怎么看这更快?即使对于少量 (2-3) 项,仅构建整个 dict 似乎也稍微快一些,可能是因为缺乏比较。这种方法可能更好的唯一情况是如果字典列表很大,因此您可以避免复制整个内容。在这种情况下,您可能希望切换到更具可扩展性的东西,例如 Pandas DataFrame。
      • @ChinmayKanchi 这就是these two 测试所说的,相当一致。现在我不是分析和优化方面的专家,所以如果这些测试有什么问题,请告诉我,但在我看来,这种方法 从 15 个项目列表中获取 2 个项目更快,至少在我的机器上。如果你不知道为什么,你需要分析生成的字节码。
      • 感谢@Chinmay 的评论 列表很大(平均有 500,000 项)。这对我来说一直很好!
      【解决方案4】:

      您可以使用字典理解执行以下操作:

      a_dict = {v['id']: v['overlap'] for v in x};
      

      这会导致:

      for id,overlap in a_dict.items():
          print(id, overlap)
      
      # output
      
      811 0.002175817439439302
      812 0.012271742728263339
      813 1.0
      814 0.9182077233294997
      815 0.8866809411969082
      816 0.9460961805523018
      817 0.7302323133830623
      818 0.81532953091762
      819 0.2817392052504116
      116 0.2038311249297872
      117 0.9173796235219325
      822 0.8503886863531487
      823 1.0
      820 0.7905202140586483
      821 0.8497466449368322
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-11-12
        • 1970-01-01
        • 1970-01-01
        • 2012-01-29
        • 1970-01-01
        • 2011-08-07
        相关资源
        最近更新 更多