Python:split函数是否在列表中多次求值?

Python:split函数是否在列表中多次求值?,python,list-comprehension,Python,List Comprehension,有件事我一直在想。在此列表中,拆分是执行一次还是多次 l = [line.split()[i] for i in indexes] 我目前确实以这种方式列出了这样的理解: l = line.rstrip().split() l = [l for i in indexes] 但我不确定是否有必要。除了肯定想知道的是/否答案外,我还想知道如何通过CPU评测或阅读一些文档来了解这一点。谢谢。列表左侧的表达式将针对每个元素重新求值,是的 如果你只需要对它进行一次评估,你需要做你所做的事情;首先调用它

有件事我一直在想。在此列表中,拆分是执行一次还是多次

l = [line.split()[i] for i in indexes]
我目前确实以这种方式列出了这样的理解:

l = line.rstrip().split()
l = [l for i in indexes]

但我不确定是否有必要。除了肯定想知道的是/否答案外,我还想知道如何通过CPU评测或阅读一些文档来了解这一点。谢谢。

列表左侧的表达式将针对每个元素重新求值,是的

如果你只需要对它进行一次评估,你需要做你所做的事情;首先调用它并存储结果,以便在列表中重复使用

从:

在这种情况下,新列表的元素是通过将
for
if
子句中的每一个看作块,从左到右嵌套,并在每次到达最里面的块时计算表达式以生成列表元素而产生的元素

我的

您还可以使用以下命令分解列表:

FOR\u ITER
操作码启动循环(使用
JUMP\u ABSOLUTE
关闭循环),每次执行
LOAD\u NAME line
LOAD\u ATTR split
CALL\u函数
。换句话说,字节码13到19实现了
line.split()
部分,并且每次都通过循环执行,循环从字节码7到29运行


(Python 3注意:列表理解有自己的作用域,您需要从外部代码对象常量中提取代码对象;
dis.dis(compile('line.split()[i]表示索引中的i'),'eval').co_consts[0])

我要补充的是,您的LC示例是对以下内容的替代:

l = []
for i in indexes:
    l.append(line.split()[i])

因此,答案肯定是肯定的,每次迭代都会对其进行评估。

正如@Dalen所说,当对列表理解进行推理时,我相信你可以期望它的行为就像你在没有理解的情况下做了同样的事情一样@Martijn展示了如何通过查看程序集来验证这一点

我的回答

  • 提供了一种自己验证行为的更简单的方法(即不需要读取程序集)

  • 在列表中的多个位置显示函数的行为(当我想知道调用“外部函数”(见下文)的频率时,我发现了这个问题)

  • 代码:


    这将打印一次调用外部和五次调用内部,验证与正常的for循环一样,外部函数和内部函数在每个循环中执行一次。

    可能重复感谢,我发现它是@tommy.carstensen的副本:我不认为那里有文档或拆卸选项。@tommy.carstensen:另一个社区成员在这个方向上被骗了,大概是因为他们觉得这个答案更好地涵盖了基础。我翻译了你的编辑,因为我没有看到你及时添加了更多信息。嗯,反汇编就是我写的。
    l = []
    for i in indexes:
        l.append(line.split()[i])
    
    def inner_func(i):
        print('called inner')
        return i
    
    def outer_func(n):
        print('called outer')
        return range(n)
    
    l = [inner_func(i) for i in outer_func(5)]