python - 是否在每次通过时构造/删除循环中使用的常量列表?

标签 python

以下代码片段是否会在每个循环中创建和销毁常量列表,这会产生任何(尽管很小)开销,还是只创建一次列表?

for i in <some-type-of-iterable>:
    if i in [1,3,5,18,3457,40567]:
        print(i)

我问的是 Python“标准”(例如存在的标准)和常见的 CPython 实现。
我知道这个例子是人为设计的,而且尝试担心使用 CPython 的性能是愚蠢的,但我只是好奇。

最佳答案

这取决于 python 实现和版本以及“常量列表”的使用方式。在 Cpython2.7.10 上以您的示例为例,答案似乎是 if 语句条件中的列表仅创建一次...

>>> def foo():
...   for i in iterable:
...     if i in [1, 3, 5]:
...       print(i)
... 
>>> import dis
>>> dis.dis(foo)
  2           0 SETUP_LOOP              34 (to 37)
              3 LOAD_GLOBAL              0 (iterable)
              6 GET_ITER            
        >>    7 FOR_ITER                26 (to 36)
             10 STORE_FAST               0 (i)

  3          13 LOAD_FAST                0 (i)
             16 LOAD_CONST               4 ((1, 3, 5))
             19 COMPARE_OP               6 (in)
             22 POP_JUMP_IF_FALSE        7

  4          25 LOAD_FAST                0 (i)
             28 PRINT_ITEM          
             29 PRINT_NEWLINE       
             30 JUMP_ABSOLUTE            7
             33 JUMP_ABSOLUTE            7
        >>   36 POP_BLOCK           
        >>   37 LOAD_CONST               0 (None)
             40 RETURN_VALUE        

注意:16 LOAD_CONST 4 ((1, 3, 5))

Python 的窥孔优化器已将我们的列表转换为元组(感谢 python!)并将其存储为常量。请注意,如果窥孔优化器知道您作为程序员绝对没有办法获得对列表的引用(否则,您可以改变列表并更改代码的含义),则它只能对对象进行这些转换。据我所知,他们只对 listset 文字进行优化,这些文字完全由常量组成,并且是 in运算符。可能还有其他我不知道的情况(dis.dis 是您找到这些优化的 friend )。

我在上面已经暗示过,但是你可以在更新的 python 版本中用集合文字做同样的事情(在 python3.2+ 中,set 被转换为常量 frozenset).这样做的好处是 set/frozenset 的成员资格测试平均比 list/tuple 快。

关于python - 是否在每次通过时构造/删除循环中使用的常量列表?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37421183/

相关文章:

python - 保存一个 'lxml.etree._ElementTree' 对象

python - 字符串中的第一个唯一字符

python - 我的问题是编写一个 python 程序来从文件中读取 2 个数字,并将这 2 个数字的 gcd 和 lcm 写入第二个文件。这是我的代码

python - 我的 python 多处理代码有什么问题?

python - 在 for 循环中使用 str.split 时为 "ValueError too many values to unpack"

python - PyQt5 - 组合框中有条件的颜色字段 - qsqltablemodel

python - 在 JSON 文件中预处理推文

c# - 在 64 位上没有修改权限的情况下,从 UNC 路径加载 .Net 程序集失败

python - 如何截断 numpy 数组中大于指定值的值?

python - 如何将 python 中 for 循环的输出写入 csv 格式的文件?