Использование print () внутри рекурсивных функций в Python3

я следую за книгой "введение в вычисления с использованием 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

если я удалить

2 ответов


на 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)

причина в том, что когда end используется с некоторым значением, отличным от "\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