如何使用 toolz 制作总是 returns 列表的 curry 版本的地图
How to make a curry version of map that always returns list using toolz
如果我使用
导入 toolz
from toolz.curried import *
那么map
会自动变成柯里化形式,所以
map(func,[[1,2],[3,4]])
可以写成
map(func)([[1,2],[3,4]])
但 curried map
总是 return 一个可迭代对象。我的方法是定义一个总是 return 列表的 curried lmap
。但简单的尝试
lmap=compose(list,map)
不行,例如
lmap(len)([[1,2],[3,4]])
会给
---------------------------------------------------------------------------
TypeError Traceback (most recent call
last) in ()
----> 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 return ret
470
TypeError: 'curry' object is not iterable
那么如何定义一个柯里化的lmap
?
你叫法不对。 map
传递给 compose 是柯里化的,但不是整个表达式。当你称它为
lmap(len)([[1,2],[3,4]])
它将 len
传递给 lmap
它 returns 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
会丢弃大部分内容。
这个问题目前在 google 工具错误 'curry' object is not iterable
结果中排在首位。另一种触发此处尚未提及的错误消息的方法是尝试将 toolz.curried.pipe
与柯里化迭代器一起使用,就好像 pipe
本身被柯里化了一样:
>>> transform = pipe(
map(lambda x: x + 1),
map(lambda x: x + x)
)
>>> list(transform([3,4,5]))
TypeError: 'curry' object is not iterable
这里第一个柯里化映射作为最后一个参数传递给第二个;
尽管从 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]
如果我使用
导入 toolzfrom toolz.curried import *
那么map
会自动变成柯里化形式,所以
map(func,[[1,2],[3,4]])
可以写成
map(func)([[1,2],[3,4]])
但 curried map
总是 return 一个可迭代对象。我的方法是定义一个总是 return 列表的 curried lmap
。但简单的尝试
lmap=compose(list,map)
不行,例如
lmap(len)([[1,2],[3,4]])
会给
---------------------------------------------------------------------------
TypeError Traceback (most recent call last) in () ----> 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 return ret
470TypeError: 'curry' object is not iterable
那么如何定义一个柯里化的lmap
?
你叫法不对。 map
传递给 compose 是柯里化的,但不是整个表达式。当你称它为
lmap(len)([[1,2],[3,4]])
它将 len
传递给 lmap
它 returns 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
会丢弃大部分内容。
这个问题目前在 google 工具错误 'curry' object is not iterable
结果中排在首位。另一种触发此处尚未提及的错误消息的方法是尝试将 toolz.curried.pipe
与柯里化迭代器一起使用,就好像 pipe
本身被柯里化了一样:
>>> transform = pipe(
map(lambda x: x + 1),
map(lambda x: x + x)
)
>>> list(transform([3,4,5]))
TypeError: 'curry' object is not iterable
这里第一个柯里化映射作为最后一个参数传递给第二个;
尽管从 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]