動画で学習内容の重要ポイントをチェックしたら、記事を読み、問題を解いて理解を深めましょう。
1 リスト内包表記 (List Comprehensions)
リスト内包表記 (list comprehension) は、“Python”言語でリストを作成する簡潔な方法です。既存のリスト、タプル、セット、または文字列などのイテラブルの各要素に式 (expression) を適用して新しいリストを生成することができます。また条件に基づいて要素をフィルタリングすることも可能です。
1.1 リスト内包表記の基本的な使い方
リスト内包表記の基本的な構造を Tip 1 に示します.
Tip 1: TIPS
new_list = [expression for item in iterable]
iterable
: リストやタプルなどのオブジェクトこのリスト内包表記の構造については深く考えないでください。これから説明を進めていきます。
リスト内包表記がどのように機能するかを、例を使って確認してみましょう:
# Using list comprehension to achieve the same result in a more concise way
squares = [i**2 for i in range(1, 11)]
print(squares)
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
各コードの説明を以下に示します:
for i in range(1, 11)
: この部分では、1から10まで(両端を含む)の数字を繰り返し処理するループが設定されています。各反復では、i
というループ変数が1、2、3、、、10という値を取ります。
i**2
: これは反復処理中の各i
の値に適用される式です。i
の2乗が計算されます。
[i**2 for i in range(1, 11)]
: このコード全体がリスト内包表記を表しています。新しいリストを生成し、1から10までの各数の2乗が要素となります。
したがって、squares = [i**2 for i in range(1, 11)]
を実行するとsquares
という名前のリストが作成され、その要素は 1
から 10
の数字の2乗となります。結果として得られるリストは [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
です。
上記のsquares
リストをリスト内包表記なしで作成することもできますが、少し長くなります:
# Create a list of squares of numbers from 1 to 10 using a for loop
squares = []
for i in range(1, 11):
squares.append(i**2)
print(squares)
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
1.2 リスト内包表記をフィルターと操作に利用する
特定の条件に基づいて要素をフィルタリングするために、リスト内包表記内で条件式を使用することもできます。例えば:
# 条件を加えたリスト内包表記の使用
evens = [i for i in range(1, 11) if i % 2 == 0]
print(evens)
[2, 4, 6, 8, 10]
i
が偶数の場合、その値がリストに追加されます。その他の場合は条件式は何も返しません。つまり、if i % 2 == 0
はフィルターのように機能します。
同じリストを通常のループで生成することもできますが、リスト内包表記の方が簡潔なため適切な方法です:
# forループを使って1から10の範囲における偶数のリストを作成する
evens = []
for i in range(1, 11):
if i % 2 == 0:
evens.append(i)
print(evens)
[2, 4, 6, 8, 10]
次の例では score
に基づいて成績を出力するという操作を行ってみましょう。リスト内包表記ではif
文と一緒にelse
文を使用することもできますが、elif
文を利用することはできません。
# リスト内包表記でif-else文を使用する例
grades = ["A" if score >= 90 else "B" if score >= 80 else "C" if score >= 70 else "D" if score >= 60 else "E" for score in [85, 77, 92, 60, 45]]
print(grades)
['B', 'C', 'A', 'D', 'E']
上記のコードでは、 [85, 77, 92, 60, 45]
を取り、値が90以上の場合は"A"
を返します。それ以外で値が80以上なら"B"
を返します。以下同様です。
条件式の構造を説明するために、上記のコードを通常のループを使って書き直します:
# リスト内包表記
# -> "elif"文がない通常のループ
scores = [85, 77, 92, 60, 45]
grades = []
for score in scores:
if score >= 90:
grades.append("A")
else:
if score >= 80:
grades.append("B")
else:
if score >= 70:
grades.append("C")
else:
if score >= 60:
grades.append("D")
else:
grades.append("E")
# 最終的な成績のリストを出力する
print(grades)
['B', 'C', 'A', 'D', 'E']
上記のコードからわかるように、ネストされた if
と else
文を使っています。これらの条件は以下と同様です:
# "elif"文がない通常のループ
# -> "elif"文がある通常のループ
scores = [85, 77, 92, 60, 45]
grades = []
for score in scores:
if score >= 90:
grades.append("A")
elif score >= 80:
grades.append("B")
elif score >= 70:
grades.append("C")
elif score >= 60:
grades.append("D")
else:
grades.append("E")
# 最終的な成績のリストを出力する
print(grades)
['B', 'C', 'A', 'D', 'E']
リスト内包表記の中でのif
やelse
構造が難しいと感じたら、ヘルパー関数を使用することができます。次のコードでは、convert_to_grade()
がヘルパー関数です(*「関数」については次の記事で説明します)。複雑な条件や操作をカプセル化させ、独立した関数を定義し、それをリスト内包表記の中で呼び出すことができます。
# リスト内包表記のためのヘルパー関数
def convert_to_grade(score):
if score >= 90:
return "A"
elif score >= 80:
return "B"
elif score >= 70:
return "C"
elif score >= 60:
return "D"
else:
return "E"
scores = [85, 77, 92, 60, 45]
grades = [convert_to_grade(score) for score in scores]
print(grades)
['B', 'C', 'A', 'D', 'E']
この方が、ずっと理解しやすく見えます。
したがって、リスト内包表記は値をフィルタリングしたり、操作して新しいリストを作成する簡潔な方法であると言えます。
TIPS
リスト内包表記を使って新しいリストを作ることができます。また以下のことを行えます:
- 値をフィルタリングする
- 値を操作する
2 Exercises