我已經習慣了類似 FP/haskell 的 reduce 概念,它已經在 Python 中作為內置庫實作了:
from functools import reduce
lst = [1,2,3,4,5]
reduce(lambda x, y: x*y, lst)
# result: 120
但是,這不適用于例如具有三個引數的 lambda:
from functools import reduce
lst = [1,2,3,4,5]
reduce(lambda x, y, z: x*y z, lst)
# expected result: (1*2 3) * 4 5
# actual result:
# TypeError: <lambda>() missing 1 required positional argument: 'z'
基本原理是保持規則“前一個結果是下一個第一個引數”。
是否有內置的實作,或者功能結構的巧妙/簡單組合來實作這樣的目標?
附:謹防偽重復
uj5u.com熱心網友回復:
一個相當簡單的實作是
import inspect
def nreduce(fn, lst):
nargs = len(inspect.signature(fn).parameters)
args = list(lst)
while len(args) >= nargs:
next_args = [args.pop(0) for x in range(nargs)]
args.insert(0, fn(*next_args))
return args
lst = [1, 2, 3, 4, 5]
print(nreduce(lambda x, y, z: x * y z, lst))
如果你想花哨,你可以使用 adeque來更快地將剛剛減少的值插入到串列的左側:
import collections
def nreduce(fn, lst):
nargs = len(inspect.signature(fn).parameters)
arg_queue = collections.deque(lst)
while len(arg_queue) >= nargs:
next_args = [arg_queue.popleft() for x in range(nargs)]
arg_queue.appendleft(fn(*next_args))
return list(arg_queue)
如果 的長度lst不能被 的數量整除fn,則其余元素也將被回傳。
另一個實作可與任何可迭代物件一起使用而無需復制到其他串列或佇列中(它不會回傳 的其余部分lst,只回傳它消耗的值):
def nreduce(fn, lst):
nargs = len(inspect.signature(fn).parameters)
lst_iter = iter(lst)
next_args = []
while True:
try:
while len(next_args) < nargs:
next_args.append(next(lst_iter))
except StopIteration:
break
next_args = [fn(*next_args)]
return next_args
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/330979.html
上一篇:使用海象運算子:=產生語法錯誤
