簡體   English   中英

Python:可以混合使用生成器和遞歸函數嗎?

[英]Python: is it possible to mix generator and a recursive function?

有沒有辦法使以下代碼起作用?

add = lambda n: (yield n) or add(n+1)

(答案不必采用功能性樣式)

我不確定“ yield(n)或add(n + 1)”的意圖,但是遞歸生成器當然是可能的。 您可能需要閱讀下面的鏈接以掌握可能的情況,特別是標題為“遞歸生成器”的部分。

def add(n):
    yield n
    for m in add(n+1):
        yield m

使用遞歸生成器,可以輕松構建復雜的回溯器:

def resolve(db, goals, cut_parent=0):
    try:
        head, tail = goals[0], goals[1:]
    except IndexError:
        yield {}
        return
    try:
        predicate = (
            deepcopy(clause)
                for clause in db[head.name]
                    if len(clause) == len(head)
        )
    except KeyError:
        return
    trail = []
    for clause in predicate:
        try:
            unify(head, clause, trail)
            for each in resolve(db, clause.body, cut_parent + 1):
                for each in resolve(db, tail, cut_parent):
                    yield head.subst
        except UnificationFailed:
            continue
        except Cut, cut:
            if cut.parent == cut_parent:
                raise
            break
        finally:
            restore(trail)
    else:
        if is_cut(head):
            raise Cut(cut_parent)

...

for substitutions in resolve(db, query):
    print substitutions

這是由遞歸生成器實現的Prolog引擎。 db是表示事實和規則的Prolog數據庫的字典。 unify()是統一函數,它將為當前目標創建所有替代並將更改附加到跟蹤中,以便以后可以撤消。 restore()執行撤消操作,is_cut()測試當前目標是否為'!',以便我們進行分支修剪。

在我看來,您的功能似乎只是未綁定序列的另一種表達方式:

n,n + 1,n + 2,....

def add(x):
    while True:
        yield x
        x+=1

for index in add(5):
    if not index<100: break ## do equivalent of range(5,100)
    print(index)

這不是遞歸的,但我認為這里不需要遞歸樣式。

基於其他答案鏈接的遞歸版本,其中有生成器調用生成器,但不是遞歸的:

from __future__ import generators

def range_from(n):
    yield n
    for i in range_from(n+1):
        yield i

for i in range_from(5):
    if not i<100: break ## until 100 (not including)
    print i

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM