在 Haskell 中有一個簡單的串列函式可用
iterate :: (a -> a) -> a -> [a]
iterate f x = x : iterate f (f x)
在python中可以實作如下:
def iterate(f, init):
while True:
yield init
init = f(init)
我有點驚訝,像這樣的基本東西不是 functools/itertools 模塊的一部分。是否可以使用這些庫中提供的工具以功能樣式(即沒有回圈)簡單地構建它?(主要是打代碼,嘗試學習 Python 中的函式式風格。)
uj5u.com熱心網友回復:
您可以使用以下功能中的一些功能來做到這一點itertools:
from itertools import accumulate, repeat
def iterate(func, initial):
return accumulate(repeat(None), func=lambda tot, _: func(tot), initial=initial)
雖然它顯然不是很干凈。Itertools 缺少一些用于構造流的基本功能,例如unfoldr. 大多數itertools函式可以用unfoldr.
uj5u.com熱心網友回復:
itertools模塊有一個第 3 方“擴展” more-iterools,其中包括(除許多其他外)一個iterate與您觀察到的完全一樣定義的函式:
# Exact definition, minus the doc string...
def iterate(func, start):
while True:
yield start
start = func(start)
Python 缺乏進行遞回定義所需的優化,例如
def iterate(func, start):
yield from chain([start], iterate(func, func(start))
可行的。
如果你很好奇,Coconut是 Python 的超集,它可以做諸如尾呼叫優化之類的事情。在https://cs121-team-panda.github.io/coconut-interpreter/嘗試以下代碼:
@recursive_iterator
def iterate(f, s) = (s,) :: iterate(f, f(s))
for x in iterate(x -> x 1, 0)$[1000:1010]:
print(x)
(我不完全確定recursive_iterator裝飾器是必要的。我認為,迭代切片演示了這避免了 Python 中類似代碼會產生的遞回深度錯誤。)
uj5u.com熱心網友回復:
您可以在生成器運算式中使用海象運算子*來獲得所需的輸出。
from itertools import chain, repeat
def f(x):
return x 10
x = 0
it = chain([x], (x:=f(x) for _ in repeat(None)))
>>> next(it)
0
>>> next(it)
10
>>> next(it)
20
*海象算子python3.8及以上版本可用
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/468444.html
上一篇:我怎樣才能設法從單子變壓器列印
