【问题标题】:Are *parameters calls lazy? [duplicate]*parameters 调用是懒惰的吗? [复制]
【发布时间】:2012-08-12 18:29:09
【问题描述】:

可能重复:
Do python's variable length arguments (*args) expand a generator at function call time?

假设你有一个这样的函数:

def give_me_many(*elements):
   #do something...

你这样称呼它:

generator_expr = (... for ... in ... )
give_me_many(*generator_expr)

元素会被延迟调用,还是生成器会在函数执行之前遍历所有可能的数百万个元素?

【问题讨论】:

标签: python lazy-evaluation generator-expression


【解决方案1】:

参数总是作为元组和/或字典传递给函数,因此使用*args 传递的任何内容都将转换为元组或**kwargs 将转换为字典。如果kwargs 已经是字典,则制作一个副本。元组是不可变的,因此 args 不需要被复制,除非它发生变化(通过包含其他位置参数或删除命名位置参数的一些参数),但它会从任何其他序列类型转换为元组。

【讨论】:

  • 听起来合乎逻辑,但我仍然没有得到与问题的联系。
  • @erikb85,调用tuple(..)(或dict(..))进行转换,强制评估整个生成器。
  • Timeit 似乎证实调用f(*some_tuple) 比调用f(*some_list) 稍快。呵呵。
【解决方案2】:

不,他们不是:

>>> def noisy(n):
...   for i in range(n):
...     print i
...     yield i
... 
>>> def test(*args):
...   print "in test"
...   for arg in args:
...     print arg
... 
>>> test(*noisy(4))
0
1
2
3
in test
0
1
2
3

【讨论】:

    【解决方案3】:

    The docs 这么说

    这些参数将被包装在一个元组中

    这意味着生成器被提前评估。

    【讨论】:

      猜你喜欢
      • 2018-02-27
      • 2021-02-04
      • 2018-01-28
      • 1970-01-01
      • 2017-01-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多