Python練習問題:出力楊輝三角(ジェネレータgenerator)

4605 ワード

#廖雪峰先生の練習問題
楊輝三角の定義は以下の通りである.
           1
          / \
         1   1
        / \ / \
       1   2   1
      / \ / \ / \
     1   3   3   1
    / \ / \ / \ / \
   1   4   6   4   1
  / \ / \ / \ / \ / \
 1   5   10  10  5   1

各行をリストと見なし、generatorを書いて、次の行のリストを出力し続けます:#--coding:utf-8--def triangles():pass
#出力n=0 results=[]for t in triangles():print(t)results.append(t)n=n+1 ifn=10:break if results=[[1],[1,1,1,[1,1,1,2,1,[1,1,1,1,3,1],[1,4,6,4,1],[1,5,10,10,10,5,1],[1,6,15,15,20,15,15,15,6,1],[1,7,21,21,35,35,21,21,7,1,[1,8,8,28,56,70,56,28,8,1,[1,9,36,84,126,126,84,84,36,36,9,9,9,1]:pripripen:pripend:pripend(1]:print(‘テスト合格!’)else:print(‘テスト失敗!’)
———–以上がテーマの内容です.--私の最初の答えは:
# -*- coding: utf-8 -*-
def triangles():
    l1 = [1]
    n = 0
    while 1:
        if n != 0:
            m = 0
            lt = l1
            while m! = n:
                if m!= 0:
                    l1[m] = lt[m-1] + lt[m]
                m = m+1
            l1.append(1)
        yield l1
        n = n+1

「テストに失敗しました!」問題はバックアップlt"lt=l 1"であり、この文はltをl 1が指すオブジェクトに指している.すなわち、2つの変数が同じオブジェクトを指している.次の「l 1[m]=lt[m-1]+lt[m]」と「l 1.append(1)」は操作対象であるため、l 1が変化するとltこのバックアップも変化するため、バックアップの役割を果たしていない
そしてバックアップの方法を
lt = [t for t in l1]

このように書くと、ltは新しいオブジェクトを指し、l 1の影響を受けずに実行した後、テストコードにprintが印刷された様子は問題ないように見えますが、「テストに失敗しました!」
コメントを見て推測するのは、list:results=[]=>>が空のresult変数として定義され、任意のオブジェクトを指さすことなくforループがジェネレータから値を取ってlist:resultsを操作するためである.appen(t)=>result[0]この変数がl 1を指す変数が再び生成器から出てくると、l 1が指す変数値が変化(すなわちresult[0]が指す変数)、すなわちresult[0]が変化し、2回目のresults.appen(t)の場合、result[1]もresult[0]、l 1と同様に同じ変数を指すので、最後にresultの実際の内容は私が見たprintが出てくるほどではありません
コードの「yield l 1」を
yield [y for y in l1]

これにより、ジェネレータが生成するたびに生成される値は、新しい変数result[0]、result[1]...を指す変数とは異なります.
最終コードは
# -*- coding: utf-8 -*-
def triangles():
    l1 = [1]
    n = 0
    while 1:
        if n != 0:
            m = 0
            lt = [t for t in l1]
            while m != n:
                if m!= 0:
                    l1[m] = lt[m-1] + lt[m]
                m = m+1
            l1.append(1)
        yield [y for y in l1]
        n = n+1

WHATEVERコメントエリア大神のコードは..
# -*- coding: utf-8 -*-
def triangles():
    L=[1]
    while True:
        yield L          
        L=[L[0]]+[L[n]+L[n+1] for n in range(len(L)-1)]+[L[-1]]