当前位置: 首页 > 面试题库 >

python插入VS追加

司寇照
2023-03-14
问题内容

我已经编写了基本的python代码段,以首先在列表中插入值,然后反转它们。我发现insert和append方法之间的执行速度存在巨大差异。

片段1:

L = []
for i in range(10**5):
 L.append(i)
L.reverse()

执行此操作所需的时间:

real    0m0.070s
user    0m0.064s
sys         0m0.008s

片段2:

l = []
for i in range(10**5):
 l.insert(0,i)

执行时间:

real    0m5.645s
user    0m5.516s
sys         0m0.020s

我希望代码片段2的性能比snippet1好得多,因为我直接通过在前面插入数字来执行反向操作。但是所花费的时间却相反。我不明白为什么后一种方法需要更多时间来执行,即使该方法看起来更优雅。有人对此有任何解释吗?


问题答案:

请注意,您的结果将取决于精确的Python实现。CPython的(和pypy)自动调整你的清单,并 获得很大的
空间,为未来的追加,从而加快append此外。

在内部,列表只是大小恒定的内存块(在 堆上
)。有时您很幸运,可以增加块的大小,但是在很多情况下,一个对象已经存在。例如,假设您为列表分配了大小为4的块[a,b,c,d],而其他代码为字典分配了大小为6的块:

Memory  0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
       |a b c d| | dictionary |

假设您的列表包含4个元素,并且添加了另一个。现在,您只需将列表的大小调整为5:

Memory  0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
       |a b c d e| dictionary |

但是,如果现在需要另一个元素,该怎么办?

好吧,您唯一可以做的就是获取一个新空间并复制列表的内容。

Memory 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
                | dictionary |a  b  c  d  e  f |

请注意,如果您批量获取空间(上述超额配置),则只需不时调整列表的大小(并可能复制)。

相反,在位置0插入时,始终需要复制列表。让我们插入x

Memory  0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
orig   |a b c d| |dictionary|
after  |x a b c d|dictionary|

尽管末尾有足够的空间来附加x,但我们必须移动所有其他值(甚至不能复制,这可能会减少内存的开销)。



 类似资料:
  • 问题内容: 使用Mongoose将文档(记录)插入MongoDB有哪些不同的方法? 我目前的尝试: 知道为什么插入和保存在我的情况下不起作用吗?我尝试创建,它插入了2个文档而不是1个。这很奇怪。 问题答案: 的是该模型的一个实例方法中,当直接从被呼叫作为一个方法调用,在本质上静态的,拍摄对象作为第一参数。 将任何您想要的功能导出到外部。 有关Mongoose Docs的 更多信息,或考虑阅读Mon

  • 问题内容: 我正在尝试编写一个脚本,该脚本会将新的用户记录追加到ElasticSearch,如果该用户已经存在,则更新任何信息,如果新对象中存在更新的PaymentInfo对象,则将其添加到用户的Payments数组中。这是到目前为止我正在使用的简化版本: 这几乎可以满足我的要求,因为它可以正确地插入文档,或者如果用户具有相同的ID,则可以更新文档,但是如果该用户已经存在,则缺少将这个Paymen

  • 问题内容: 可能是我正在分裂头发,但我想知道以下情况: 最好使用哪个? 我最好的意思是 任何方式 。 阅读这些内容后,其他帖子说案例3并不是最佳性能,其他案例1会以案例3结束,依此类推。 更具体。 例如,搁置一旁,如果必须维护他的代码,哪种风格更适合从其他程序员那里看到呢? 还是您认为哪种编程更有效? 否则您会认为速度更快等。 我不知道该如何表达。 像案例3这样的答案可能会更快,但是绝大多数程序员

  • 嗨! 我需要扫描mysql(5.1)上的一个非常大的表, 该表大致如下: 我需要将main_id+键的所有唯一值获取到一个新表中。 使用以下查询需要花费大量时间(在非常快的服务器上3天后仍在运行): 所以我的问题是- 这会更快吗?

  • 问题内容: 逐块构建大型数据帧时,Pandas的性能令我感到困惑。在Numpy中,通过预分配一个大的空数组然后填充值,我们(几乎)总是可以看到更好的性能。据我了解,这是由于Numpy立即获取其所需的所有内存,而不是每次操作都必须重新分配内存。 在Pandas中,通过使用该模式,我似乎获得了更好的性能。 这是一个带有计时的例子。该类的定义如下。如您所见,我发现预分配比使用!慢大约10倍。使用适当的d

  • 二叉搜索树(BST)和二叉树(BT)中的插入有什么区别?我知道,在BST中,您将新节点的值与根进行比较,如果较小,则添加到其左侧,如果较大,则将其添加到根的右侧。BT的程序是否相同?如果没有,插入和移除的步骤是什么?