【问题标题】:How to make a curry version of map that always returns list using toolz如何使用 toolz 制作始终返回列表的咖喱版地图
【发布时间】:2017-11-16 06:36:05
【问题描述】:

如果我使用导入 toolz

from toolz.curried import *

那么map会自动变成柯里化形式,所以

map(func,[[1,2],[3,4]])

可以写成

map(func)([[1,2],[3,4]])

但是 curried map 总是返回一个可迭代对象。我定义了一个总是返回列表的咖喱lmap。不过简单试试

lmap=compose(list,map)

不会工作,例如

lmap(len)([[1,2],[3,4]])

会给

----------------------------------- ----------------------------
TypeError Traceback(最近调用 最后)在() ----> 1 lmap(len)([[1,2],[3,4]])

C:\ProgramData\Anaconda3\lib\site-packages\toolz\functoolz.py in
call(self, *args, **kwargs)
466 ret = self.first(*args, **kwargs)
467 for f in self.funcs:
--> 468 ret = f(ret)
第469话
470

TypeError: 'curry' 对象不可迭代

那么如何定义一个柯里化的lmap

【问题讨论】:

    标签: python toolz


    【解决方案1】:

    你叫错了。 map 被传递给 compose 是柯里化的,但不是整个表达式。当你这样称呼它时

    lmap(len)([[1,2],[3,4]])
    

    它将len 传递给lmap 它返回toolz.functoolz.curry 等价于

    map(len)
    

    然后尝试调用list

    list(map(len))
    

    这显然行不通。如果它没有失败,完整的表达式将相当于:

    list(map(len))([[1,2],[3,4]])
    

    而您正在寻找的电话是:

    list(map(len), [[1,2],[3,4]])
    

    所以实际上柯里化在这里没有多大意义。

    您可能想要以下几行:

    def lmap(g): return compose(list, map(g)) 
    

    可以根据需要调用:

    >>> lmap(len)([[1,2],[3,4]])
    [2, 2]
    

    但老实说,这个问题看起来有点人为——toolz 在统一懒惰方面的最大优势。转换为 list 会丢弃大部分内容。

    【讨论】:

      【解决方案2】:

      此问题目前在工具z 错误'curry' object is not iterable 的谷歌搜索结果中名列前茅。触发这里尚未提及的此错误消息的另一种方法是尝试将 toolz.curried.pipe 与 curried 迭代器一起使用,就好像 pipe 本身已被 curried:

      >>> transform = pipe(
          map(lambda x: x + 1),
          map(lambda x: x + x)
          )
      >>> list(transform([3,4,5]))
      TypeError: 'curry' object is not iterable
      

      这里第一个 curried map 作为最后一个参数传递给第二个; 尽管从 curried 命名空间重新导出,但 pipe 没有被 curried。解决方案是升级到 toolz 版本 0.10.0,如果还没有使用它并使用 toolz.curried.compose_left 代替它实际上是一个 curried pipe

      >>> transform = compose_left(
          map(lambda x: x + 1),
          map(lambda x: x + x)
          )
      >>> list(transform([3,4,5]))
      [8, 10, 12]
      

      【讨论】:

      • 虽然这对于在谷歌上搜索该错误的人可能有用,但它并不能真正回答问题。这只是一些与这个特定问题无关的信息。
      • 由于这不能直接回答 OP 的问题,它可能会在某个时候通过同行评审被删除。就我个人而言,我不希望看到这些信息被删除,因为它看起来非常有用。 @qwitwa 我建议您将此作为新问题发布,自己回答+接受,然后在对此问题的评论中链接到您的新帖子。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-12-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-11-13
      • 2018-02-02
      相关资源
      最近更新 更多