Python:生成元组的语句的执行顺序是否有保证?多语句 lambda

mut*_*oid 3 python lambda tuples python-3.x

我想知道与下面绘制的代码类似的代码在 Python 中是否合法并且可以安全使用:

# Example usage of a lambda which executes a statement and returns the changed operand
skip_first = lambda iterator: (next(iterator), iterator)[1]
Run Code Online (Sandbox Code Playgroud)

使用这样的构造并期望 lambda 的返回值是一个从原始迭代器的第二个元素开始的迭代器(如果没有抛出异常)是否安全?

或者 fi Cythonnext出于某种原因优化调用可能是合法的(即,因为它丢弃了结果值,因为未定义元组中的执行顺序,并且它可以确定我们以任何一种方式丢弃第一个值?)

  1. 用法示例:
f = iter([0, 1, 2, 3, 4])
print(list(skip_first(f)))
Run Code Online (Sandbox Code Playgroud)
  1. Godbolt 的例子

che*_*ner 5

是的,表达式列表中的表达式保证从左到右计算。来自语言文档第 6.15 节

expression_list    ::=  expression ("," expression)* [","]
starred_list       ::=  starred_item ("," starred_item)* [","]
starred_expression ::=  expression | (starred_item ",")* [starred_item]
starred_item       ::=  assignment_expression | "*" or_expr
Run Code Online (Sandbox Code Playgroud)

除了列表或集合的一部分显示时,包含至少一个逗号的表达式列表会产生一个元组。元组的长度是列表中表达式的数量。表达式从左到右计算。

在您的具体示例中,next无法优化调用,因为它可能(并且确实)有副作用(即,它修改了迭代器的内部状态)。只有在没有可变值的语言中,您才能消除不使用返回值的函数调用。如果一个函数可能发生变异的值,你必须假设它确实并允许进行呼叫。否则,您正在改变所编写代码的语义。