【问题标题】:Expression comprehension in function argument [duplicate]函数参数中的表达式理解
【发布时间】:2020-02-21 15:19:36
【问题描述】:

为什么是这个代码

sum(x for x in range(10))

有效吗?为什么不需要将x for x in range(10) 括在方括号中?

【问题讨论】:

  • 严格来说,这里都不需要,sum(range(10))
  • @khelwood,所以sum(x for x in range(10)) 被隐式转换为sum(<generator expression>)?我做对了吗?那么这种行为有多可靠呢?
  • 完全可靠。这是语言的一部分。如果你写(<x> for <y> in <z>),你就写了一个生成器表达式。
  • @khelwood,你可能是对的,但我提出了同样的担忧,因为我在下面回答了它。当然sum(X) 表示X 赋予sum 函数。如果是这种情况,Xx for x in range(10) 而不是生成器 (x for x in range(10))

标签: python


【解决方案1】:

我认为这在 cmets 中已经说了很多,但是为了后代:(Python 3.8.0) 文档的Section 6.2.8 声明“[t]在只有一个参数的调用中可以省略括号。参见详情请参阅Calls 部分。”

编辑:并且,为了完整起见,“调用”部分继续说调用的实际参数可以是逗号分隔的参数列表,也可以是单个comprehension,即x for x in ...没有括号的东西。

【讨论】:

    【解决方案2】:

    它创建一个生成器表达式。

    >>> nums = (x for x in range(4))
    >>> nums
    <generator object <genexpr> at 0x000001E52747B2B0>
    >>> next(nums)
    0
    >>> next(nums)
    1
    >>> next(nums)
    2
    >>> next(nums)
    3
    >>> next(nums)
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    StopIteration
    

    什么是生成器?除非被要求执行,否则它基本上不会执行。列表解析将首先创建一个 list,然后将该 list 传递给 sum 函数。

    去掉方括号使它成为一个生成器,它将每个生成的值发送到sum,而无需显式创建列表。 sum 将继续向genexpr 询问数字,并在StopIteration 出现时停止。这比使用列表推导要快。

    如果您有一个很长的序列,并且您使用带有 sum 函数的列表推导式,python 将首先花费时间来生成整个列表,然后 sum 将再次计算所有元素的总和。使用带有 sum 的生成器表达式将减少很多执行时间,因为 sum 会在生成每个值后立即获取。

    【讨论】:

    • “这比使用列表理解要快” ... 仅适用于大型 n
    • (x for x in range(4)) 是生成器,但x for x in range(4) 是?这就是你给sum的东西,不是吗?
    • @paxdiablo,显然你可以省略它们,但前提是生成器表达式是唯一的参数。
    • @paxdiablo ... for ... in ... 直接在括号内创建一个生成器,两边没有任何逗号。它们不需要是“自己的”括号
    • @donkopotamus:好的,有道理,list(x for x in range(4)) 也可以。
    猜你喜欢
    • 1970-01-01
    • 2019-10-27
    • 1970-01-01
    • 1970-01-01
    • 2016-05-18
    • 1970-01-01
    • 1970-01-01
    • 2018-01-27
    • 1970-01-01
    相关资源
    最近更新 更多