在Python3中使用递归函数内的print()

gos*_*os1 7 python recursion python-3.x

我正在阅读Ljubomir Perkovic撰写的"使用Python计算简介"一书,我在本书的递归部分中遇到了一个例子.代码如下:

def pattern(n):
    'prints the nth pattern'
    if n == 0:    # base case
        print(0, end=' ')
    else:    #recursive step: n > 0
        pattern(n-1)         # print n-1st pattern
        print(n, end=' ')    # print n
        pattern(n-1)         # print n-1st pattern
Run Code Online (Sandbox Code Playgroud)

例如,pattern(1)输出应该是0 1 0,并且应该水平显示.但是,在调用该函数时pattern(1),没有任何内容打印出来.但如果后面跟不带参数的print语句,则会显示结果.

>>>pattern(1)
>>>print()
0 1 0
Run Code Online (Sandbox Code Playgroud)

如果我删除递归函数end中的print()函数的参数,我得到正确的输出(尽管它垂直显示):

>>> pattern(1)
0
1
0
Run Code Online (Sandbox Code Playgroud)

这让我觉得递归代码本身是正确的(加上我确认它是由本书的网站提供的源代码,以及勘误表).但是print,如果end包含参数,我不确定为什么语句不会在函数运行时打印输出.任何帮助将不胜感激.

Bak*_*riu 7

print功能并不总是刷新输出.你应该明确地冲洗它:

import sys

def pattern(n):
    'prints the nth pattern'
    if n == 0:    # base case
        print(0, end=' ')
    else:    #recursive step: n > 0
        pattern(n-1)         # print n-1st pattern
        print(n, end=' ')    # print n
        pattern(n-1)         # print n-1st pattern
    sys.stdout.flush()
Run Code Online (Sandbox Code Playgroud)

请注意,在python3.3上print有一个新的关键字参数flush,可用于强制刷新输出(从而避免使用sys.stdout.flush).


一般来说,我将输出与模式分离,例如:

def gen_pattern(n):
    if n == 0:
        yield 0
    else:
        for elem in gen_pattern(n-1):
            yield elem
        yield n
        for elem in gen_pattern(n-1):
            yield elem

def print_pattern(n):
    for elem in gen_pattern(n):
        print(elem, end=' ')
     sys.stdout.flush()
Run Code Online (Sandbox Code Playgroud)

这使得代码更加灵活和可重用,并且具有flush仅调用一次的优点,或者您也可以在每个x元素上调用一次(实际上我相信print已经这样做了.如果尝试在屏幕上写入许多字符,它会刷新).

在python3.3中,代码可以简化一点:

def gen_pattern(n):
    if n == 0:
        yield 0
    else:
        yield from gen_pattern(n-1)
        yield n
        yield from gen_pattern(n-1)
Run Code Online (Sandbox Code Playgroud)

  • 但是,在交互式shell中没有刷新似乎很奇怪. (3认同)

Ash*_*ary 5

原因是当end与 a 以外的某个值一起使用时,"\n"打印函数会累积整个值并仅在要打印换行符或循环结束时才打印输出。

查看这两个程序的区别:

In [17]: for x in range(5):
    print(x,end=" ")
    if x==3:
       print(end="\n")
    sleep(2)
   ....:     
0 1 2 3  #first this is printed
4        #and then after a while this line is printed
In [18]: for x in range(5):
    print(x,end=" ")
    if x==3:
       print(end="\t")
    sleep(2)
   ....:     
0 1 2 3     4   #whole line is printed at once
Run Code Online (Sandbox Code Playgroud)