2013-04-25 18 views
7

私は、Ljubomir PerkovicによるPythonを使用したコンピューティングの紹介の本を読んでおり、本の再帰セクションの例の1つに問題があります。次のようにコードは次のとおりです。Python3で再帰関数の中でprint()を使用する

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 

私は、再帰関数内print()機能のend引数を削除した場合(それが垂直に表示するが)、私は正しい出力を得る:

>>> pattern(1) 
0 
1 
0 

これは、私はその再帰コード自体と思わせます正解です(私はそれが本のウェブサイトと正誤表で提供されたソースであることを確認しました)。しかし、endパラメータが含まれていると、printステートメントが関数の実行時に出力を出力しない理由はわかりません。どんな助けでも大歓迎です。

+0

この問題は、IDE-特異的であってもよいです。 Ubuntu/gnome-terminal(またはIPython + emacs)で動作するPython3を使用しているとは思われません。 – unutbu

答えて

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にあなたが強制的に出力をフラッシュ(したがってsys.stdout.flushを使用しないよう)するために使用することができ、新たなキーワード引数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要素ごとに1回呼び出すこともできます(実際には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) 
+3

しかし、インタラクティブなシェルでフラッシュしないのは、非常に奇妙なようです。 –

+0

@LevLevitskyあなたが 'pattern(1); time.sleep(10) ' – Bakuriu

+0

それはそれをしました!ありがとう! – gos1

4

理由は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 
関連する問題