如果我使用
导入toolzfrom toolz.curried import *
然后map
将自动变为curry形式,所以
map(func,[[1,2],[3,4]])
可以写成
map(func)([[1,2],[3,4]])
但curried map
总是返回一个可迭代的。我的方法是定义一个总是返回列表的curry lmap
。但是简单的尝试
lmap=compose(list,map)
不起作用,例如
lmap(len)([[1,2],[3,4]])
将给出
----------------------------------------------- ----------------------------
TypeError Traceback(最近一次调用 最后)in() ----> 1 lmap(len)([[1,2],[3,4]])C:\ ProgramData \ Anaconda3 \ lib \ site-packages \ toolz \ functoolz.py in
致电(自我,* args,** kwargs)
466 ret = self.first(* args,** kwargs)
467 for f in self.funcs:
- > 468 ret = f(ret)
469返回 470
TypeError:'咖喱'对象不可迭代
那么如何定义一个有条理的lmap
?
答案 0 :(得分:2)
你的方式是错误的。被传递给撰写的map
是咖喱,但不是一个完整的表达。当你把它称为
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]])
所以实际上currying在这里没有多大意义。
你可能想要这些内容:
def lmap(g): return compose(list, map(g))
可根据需要调用:
>>> lmap(len)([[1,2],[3,4]])
[2, 2]
但说实话,问题看起来有点人为 - toolz
在统一懒惰中的最大优势。转换为list
会抛弃大部分内容。
答案 1 :(得分:0)
此问题目前在Google搜索结果中排在第一位,原因是Toolz错误'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命名空间中重新导出的,但管道却不是curried的。解决方案是升级到尚未使用的toolz版本0.10.0(如果尚未使用的话),而改用toolz.curried.compose_left
,它实际上是咖喱pipe
:
>>> transform = compose_left(
map(lambda x: x + 1),
map(lambda x: x + x)
)
>>> list(transform([3,4,5]))
[8, 10, 12]