【问题标题】:Fast way to copy dictionary in Python在 Python 中复制字典的快速方法
【发布时间】:2011-08-17 05:14:08
【问题描述】:

我有一个 Python 程序,它可以大量使用字典。我必须复制字典数千次。我需要密钥和相关内容的副本。副本将被编辑,并且不得链接到原件(例如,副本中的更改不得影响原件。)

键是字符串,值是整数 (0/1)。

我目前使用一个简单的方法:

newDict = oldDict.copy()

分析我的代码显示复制操作花费了大部分时间。

dict.copy() 方法是否有更快的替代方法?什么速度最快?

【问题讨论】:

  • 如果值可以是 0 或 1,bool 会比int 更好吗?
  • 如果您需要数千个副本,位掩码会更好吗?
  • @Samir 在 Python 中不是 bool,无论如何命名为 int
  • 不过,我同意位掩码可能对您更有效(实际上取决于您如何使用此“dict”)。
  • 澄清一下,bool 类型实际上是int 类型的子类(子类型?)。

标签: python performance dictionary copy


【解决方案1】:

您能否提供一个代码示例,以便我了解您是如何使用 copy() 以及在什么情况下使用的?

你可以使用

new = dict(old)

但我不认为它会更快。

【讨论】:

    【解决方案2】:

    根据您留给猜测的内容,您可能想要包装原始字典并进行某种写时复制。

    “副本”是一个字典,它在“父”字典中查找内容,如果它还没有包含密钥 --- 但它本身会填充修改。

    这假设您不会修改原始文件,并且额外的查找最终不会花费更多。

    【讨论】:

      【解决方案3】:

      如您所说,显然 dict.copy 更快。

      [utdmr@utdmr-arch ~]$ python -m timeit -s "d={1:1, 2:2, 3:3}" "new = d.copy()"
      1000000 loops, best of 3: 0.238 usec per loop
      [utdmr@utdmr-arch ~]$ python -m timeit -s "d={1:1, 2:2, 3:3}" "new = dict(d)"
      1000000 loops, best of 3: 0.621 usec per loop
      [utdmr@utdmr-arch ~]$ python -m timeit -s "from copy import copy; d={1:1, 2:2, 3:3}" "new = copy(d)"
      1000000 loops, best of 3: 1.58 usec per loop
      

      【讨论】:

      • 感谢比较!将尝试重写代码以避免在大多数地方使用 dict 复制。再次感谢!
      • 在不计算每次导入成本的情况下进行最后一次比较的方法是使用timeit-s参数:python -m timeit -s "from copy import copy" "new = copy({1:1, 2:2, 3:3})"。当你在做的时候,也拉出 dict 创建(对于所有示例。)
      • 也许多次重复这个过程会更好,因为一个特定的镜头可能会有一些波动。
      • Timeit 做到了;正如它所说,它循环了 1000000 次并取平均值。
      • 我的时间有冲突。 a = {b: b for b in range(10000)} 在 [5] 中:%timeit copy(a) 10000 次循环,最佳 3:每个循环 186 µs 在 [6] 中:%timeit deepcopy(a) 100 次循环,最好的 3:每个循环 14.1 ms 在 [7] 中:%timeit a.copy() 1000 个循环,最好的 3:每个循环 180 µs
      【解决方案4】:

      查看 Python dict 操作的 C source,您可以看到它们做了一个非常幼稚(但有效)的复制。它基本上归结为对PyDict_Merge的调用:

      PyDict_Merge(PyObject *a, PyObject *b, int override)
      

      这会快速检查它们是否是同一个对象以及它们是否包含对象。之后,它会对目标字典进行一次慷慨的调整大小/分配,然后一个一个地复制元素。我没有看到你比内置的 copy() 快得多。

      【讨论】:

      • 听起来我最好重写代码以避免使用字典——或者使用更快的数据结构来完成同样的工作。非常感谢您的回答!
      【解决方案5】:

      但测量值取决于字典大小。对于 10000 个条目,copy(d) 和 d.copy() 几乎相同。

      a = {b: b for b in range(10000)} 
      In [5]: %timeit copy(a)
      10000 loops, best of 3: 186 µs per loop
      In [6]: %timeit deepcopy(a)
      100 loops, best of 3: 14.1 ms per loop
      In [7]: %timeit a.copy()
      1000 loops, best of 3: 180 µs per loop
      

      【讨论】:

        【解决方案6】:

        我意识到这是一个旧线程,但这是搜索引擎中“dict copy python”的高结果,以及“dict copy performance”的最高结果,我相信这是相关的。

        从 Python 3.7 开始,newDict = oldDict.copy() 的速度比以前快了 5.5 倍。值得注意的是,目前,newDict = dict(oldDict) 似乎没有这种性能提升。

        还有一点信息here

        【讨论】:

          猜你喜欢
          • 2011-05-22
          • 1970-01-01
          • 1970-01-01
          • 2019-10-04
          • 1970-01-01
          • 1970-01-01
          • 2019-12-03
          • 2011-05-08
          • 1970-01-01
          相关资源
          最近更新 更多