我正在阅读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
例如,对于pattern(1)
,输出应为0 1 0
,并且应该水平显示。但是,在调用函数pattern(1)
时,没有任何内容打印出来。但如果后面跟不带参数的print语句,则会显示结果。
>>>pattern(1)
>>>print()
0 1 0
如果我删除递归函数中end
函数的print()
参数,我会得到正确的输出(虽然它会垂直显示):
>>> pattern(1)
0
1
0
这让我觉得递归代码本身是正确的(加上我确认它是由本书网站提供的源代码,以及勘误表)。但是,如果包含print
参数,我不确定为什么end
语句不会在函数运行时打印输出。任何帮助将不胜感激。
答案 0 :(得分: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()
请注意,在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()
这使得代码更具灵活性和可重用性,并且具有仅调用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)
答案 1 :(得分:4)
原因是当end
与"\n"
以外的某个值一起使用时,print函数会累积整个值并仅在打印换行符或循环时打印输出结束了。
看看这两个程序的不同之处:
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