Python練習問題:出力楊輝三角(ジェネレータgenerator)
4605 ワード
#廖雪峰先生の練習問題
楊輝三角の定義は以下の通りである.
各行をリストと見なし、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(‘テスト失敗!’)
———–以上がテーマの内容です.--私の最初の答えは:
「テストに失敗しました!」問題はバックアップlt"lt=l 1"であり、この文はltをl 1が指すオブジェクトに指している.すなわち、2つの変数が同じオブジェクトを指している.次の「l 1[m]=lt[m-1]+lt[m]」と「l 1.append(1)」は操作対象であるため、l 1が変化するとltこのバックアップも変化するため、バックアップの役割を果たしていない
そしてバックアップの方法を
このように書くと、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」を
これにより、ジェネレータが生成するたびに生成される値は、新しい変数result[0]、result[1]...を指す変数とは異なります.
最終コードは
WHATEVERコメントエリア大神のコードは..
楊輝三角の定義は以下の通りである.
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]]