【问题标题】:Python for-loop with generator expression worth it for already existing dictionary?带有生成器表达式的 Python for 循环对于已经存在的字典是否值得?
【发布时间】:2021-05-13 23:49:11
【问题描述】:

我有一个模拟器程序,它对现有字典中的所有对象进行大量循环。字典包含几十万个对象,每个对象都有功能和属性。

我想知道在为每个循环创建生成器表达式时如何权衡速度/内存,以及这是否比简单地遍历字典中的值更好。对于许多循环,循环内也会有一个 if 语句。

简单的 for 循环和 if 语句示例:

for obj in dict.values():
    if obj.attr or n.state=='value':
        obj.someFunction()

生成器表达式示例:

for obj in (n for n in dict.values() if n.attr or n.state=='value'):
        obj.someFunction()

所以我真正想知道的是:在这里创建一个生成器有什么意义吗?或者这是否只需要更多时间并增加复杂性,因为字典已经存在于内存中? 我对所用的时间做了一些测试,看起来这个程序的差异可以忽略不计,所以我最感兴趣的是可能的内存使用情况。

【问题讨论】:

  • 你试过用perf_counter进行测试吗?
  • 我没有,不过我用timeit做了一些简单的测试,时差没什么好说的。将更新问题以反映这一点!
  • 我希望这会稍微慢一些,并且没有空间优势,(怎么可能?)。第一种方法是最易读/惯用的。您的生成器表达式只是无论如何都在字典上循环,那么它怎么能更快呢?
  • 使用循环+生成器而不是循环总是会有开销,如果只是通过额外的生成器对象来创建/存储/迭代。是什么让您认为为此添加生成器可能会有优势?
  • @helge 通过for 循环的迭代已经很懒惰了。您可以将生成器视为一流的迭代——如果您已经迭代,则毫无意义。生成器对于传递迭代很有用,这里不需要。

标签: python list for-loop generator-expression


【解决方案1】:

使用这样的生成器根本没有任何优势。两种变体都需要在dict.values() 上进行迭代,都需要通过if n.attr or n.state=='value' 进行过滤——生成器仅添加生成器对象本身的开销以及额外的内部迭代。
虽然这种开销很小,但实际上没有任何优势。

选择显式for 语句和if 语句。它在性能和可读性方面都更好。

【讨论】:

    猜你喜欢
    • 2012-03-06
    • 2021-01-12
    • 2018-04-26
    • 2022-11-21
    • 2011-04-23
    • 2021-07-07
    • 1970-01-01
    • 2011-01-22
    • 2019-03-22
    相关资源
    最近更新 更多