【问题标题】:itertools.islice raise a ValueError when used with functools.partial与 functools.partial 一起使用时,itertools.islice 会引发 ValueError
【发布时间】:2018-01-28 08:00:55
【问题描述】:

考虑以下python会话(3.6.1):

>>> from itertools import islice
>>> l = [i for i in range(10)]
>>> islice(l, 0, 1)
<itertools.islice object at 0x7f87c9293638>
>>> (lambda it: islice(it, 0, 1))(l)
<itertools.islice object at 0x7fe35ab40408>

这里没有什么是出乎意料的。现在,functools.partial:

>>> from functools import partial
>>> partial(islice, 0, 1)(l)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: Stop argument for islice() must be None or an integer: 0 <= x <= sys.maxsize.

partial 似乎以一种非常意想不到的方式干扰了islice 的行为。

这种行为背后的原因是什么?这是因为 islice 不处理关键字参数,like str.split few versions ago 吗?

【问题讨论】:

    标签: python valueerror


    【解决方案1】:

    位置参数在其他位置参数之后传递。所以partial(islice, 0, 1)(l)islice(0, 1, l) 是一回事,这样是行不通的。

    您不能使用局部变量以不同的顺序传递参数;只有关键字参数才允许这样做。由于islice 不接受关键字参数,您不能在此处使用partial()

    您唯一的选择是使用lambda

    【讨论】:

      【解决方案2】:

      问题在于:

      partial(islice, 0, 1)
      

      翻译为:

      islice(0, 1, l)
      

      失败是因为islice 期望它的参数按特定顺序。但是,以这种方式使用 partial 会导致参数以错误的顺序传递。如果您将虚拟函数传递给partial,您可以自己看到这一点:

      >>> def func(*args):
          print('args:', args)
      
      
      >>> partial(func, 0, 1)(l)
      args: (0, 1, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
      

      因为你不能使用islice 的关键字参数来改变参数的传递顺序,所以你不能在这里使用partial。正如@Martijn Pieters 所说,只需使用普通函数或lambda

      >>> from itertools import islice
      >>> from functools import partial
      >>> 
      >>> f = lambda l: islice(l, 0, 1)
      >>> l = [i for i in range(10)]
      >>> list(f(l))
      [0]
      

      【讨论】:

      • 传递可变部分来生成部分很少有用。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-07
      • 2018-11-24
      • 1970-01-01
      • 1970-01-01
      • 2019-11-14
      相关资源
      最近更新 更多