実践・上級問題チェック
問題 25 /40
次のresultと同じ結果になるものはどれか。
result = []
for i in 'AB':
for v in 'AB':
result.append(i + v)
選択肢はすべて、itertoolsモジュールをインポートしているものとする。
選択 1
[i[0] + i[1] for i in itertools.permutations('AB', 2)]
選択 2
[i[0] + i[1] for i in itertools.combinations('AB', 2)]
選択 3
[i[0] + i[1] for i in itertools.product('AB', repeat=2)]
選択 4
[i[0] + i[1] for i in itertools.combinations_with_replacement('AB', 2)]
解説
選択肢3が正解です。
パラメータの総当たりテストやデータの自動生成など、文字列やリストの組み合わせを作る場面はよくあります。
問題文は、文字列ABの2文字の組み合わせをすべて生成してリストにしています。
result = []
for i in 'AB':
for v in 'AB':
result.append(i + v)
print(result)
▶︎
['AA', 'AB', 'BA', 'BB']
【選択肢1】
[i[0] + i[1] for i in itertools.permutations('AB', 2)]
▶︎
['AB', 'BA']
permutations()は順列です。
順列とは、区別可能なn個のものからk個を選んで順に並べます。一度選んだ要素は使わないため、AAのような並びは出力しません。
permutations()は、第1引数で出力対象のイテラブルオブジェクト、第2引数でタプルの要素数を指定します。順列の「区別可能なn個」を第一引数で指定し、「k個」を第二引数で指定することになります。
permutations()の戻り値は、順列を順に生成するイテレーターで、中身はタプルです。リスト化すると以下になります。
list(itertools.permutations('AB', 2))
▶︎
[('A', 'B'), ('B', 'A')]
選択肢1の場合、for文でタプルから一つずつ要素を取り出し、リスト内包表記で文字を結合してリスト化しています。
【選択肢2】
[i[0] + i[1] for i in itertools.combinations('AB', 2)]
▶︎
['AB']
combinations()は、重複なしの組み合わせを出力します。
ABとBAのように同じ要素の組み合わせも出力されません。
【選択肢3】
[i[0] + i[1] for i in itertools.product('AB', repeat=2)]
▶︎
['AA', 'AB', 'BA', 'BB']
product()は、引数のイテラブルオブジェクトに対して、すべての組み合わせを返します。
デカルト積(直積)と呼ばれており、問題文のネストされたfor文と同じ結果になります。
なお、itertoolsモジュールの各関数は第2引数でタプルの要素数を指定しますが、product()だけは「repeat=n」の形式で指定します。
【選択肢4】
[i[0] + i[1] for i in itertools.combinations_with_replacement('AB', 2)]
▶︎
['AA', 'AB', 'BB']
combinations_with_replacement()は、重複ありの組み合わせを出力します。
ABとBAのように同じ要素の組み合わせは出力されません。
まとめると以下になります。
■ permutations()
['AB', 'BA']
重複なし。順番に並べる。
■ combinations()
['AB']
重複なし。順番に並べて、同じ組み合わせなし。
■ product()
['AA', 'AB', 'BA', 'BB']
重複あり。すべての組み合わせを並べる。
■ combinations_with_replacement()
['AA', 'AB', 'BB']
重複あり。順番に並べて、同じ組み合わせなし。
(公式書籍 p.213-214)