【问题标题】:why can't yield be used in a recursive function为什么不能在递归函数中使用 yield
【发布时间】:2014-01-18 13:17:00
【问题描述】:

我正在使用递归来获取列表的排列。这是我写的,但yield 版本不起作用:

def test_permutation_rec():
    print "test 2"
    permutation_rec2([1,2,3],[])     
    print "test 1"
    for one in permutation_rec1([1,2,3],[]):
        print "one:",one 

def permutation_rec1(onelist,prelist):  
    if onelist == [] :
        print prelist
        yield prelist

    lenlist= len(onelist)
    for i, oneitem in enumerate(onelist) :
        leftlist = [onelist[j] for j in range(0,lenlist) if j != i]
        permutation_rec1(leftlist,prelist + [oneitem])

def permutation_rec2(onelist,prelist):
    if onelist == [] :
        print prelist

    lenlist= len(onelist)
    for i, oneitem in enumerate(onelist) :
        leftlist = [onelist[j] for j in range(0,lenlist) if j != i]
        permutation_rec2(leftlist,prelist + [oneitem])

if __name__ == "__main__":
    test_permutation_rec()

结果:

test 2
[1, 2, 3]
[1, 3, 2]
[2, 1, 3]
[2, 3, 1]
[3, 1, 2]
[3, 2, 1]
test 1

我想我使用 yield 就像在 this the answer 中一样。

谁能告诉我为什么yield不生效?

顺便说一句,leftlist = [onelist[j] for j in range(0,lenlist) if j != i]permutation_rec2,我觉得很丑。当列表很大时,它会创建许多临时列表。我该如何改进呢?

【问题讨论】:

  • 供将来参考 - 如果您确实需要获得排列,只需使用 itertools 模块。
  • 是的。你是对的。像itertools.permutations([1,2,3]) 这样的东西有人能找到我发布的 tmplist 吗?看来这不是最好的解决方案。
  • 我遗漏了什么可以添加以使您不接受我的回答吗? :-)
  • 我昨天查看了答案。对不起,可能是点击错误,

标签: python algorithm recursion generator yield


【解决方案1】:

你需要传递递归调用的结果;每个调用都会返回一个 generator 并且您必须对其进行迭代。您链接到的答案当然也会在递归调用中循环。

permutation_rec1() 上添加一个for 循环并将每个结果值传递给下一个调用者:

def permutation_rec1(onelist, prelist):  
    if not onelist:
        yield prelist

    lenlist = len(onelist)
    for i, oneitem in enumerate(onelist):
        leftlist = [onelist[j] for j in range(lenlist) if j != i]
        for res in permutation_rec1(leftlist, prelist + [oneitem]):
            yield res

如果您使用的是 Python 3.3 或更高版本,则可以使用新的yield from generator delegation syntax

def permutation_rec1(onelist,prelist):  
    if not onelist:
        yield prelist

    lenlist = len(onelist)
    for i, oneitem in enumerate(onelist):
        leftlist = [onelist[j] for j in range(lenlist) if j != i]
        yield from permutation_rec1(leftlist, prelist + [oneitem])

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-08-02
    • 1970-01-01
    • 1970-01-01
    • 2022-01-24
    • 2019-09-13
    • 2021-01-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多