Python 3のリスト内包表記を理解する

前書き

List comprehensionsは、既存のリストに基づいてlistsを作成する簡潔な方法を提供します。 リスト内包表記を使用する場合、リストは、stringstuplesを含む任意のiterableを利用して作成できます。

構文的には、リスト内包表記は、式とそれに続くfor句を含む反復可能オブジェクトで構成されます。 この後に追加のforまたはif句を続けることができるため、for loopsおよびconditional statementsに精通していると、リスト内包表記をよりよく理解するのに役立ちます。

リスト内包表記は、リストやその他の順次data typesを作成するための代替構文を提供します。 forループなどの他の反復方法を使用してリストを作成することもできますが、プログラムで使用される行数を制限できるため、リスト内包表記が推奨される場合があります。

リスト内包表記

Pythonでは、リスト内包表記は次のように構築されます。

list_variable = [x for x in iterable]

リストまたはその他の反復可能なものが変数に割り当てられます。 iterable内の項目を表す追加の変数は、for句を中心に作成されます。 inキーワードは、forループでそのまま使用され、iterableを反復処理します。

文字列に基づいてリストを作成する例を見てみましょう。

shark_letters = [letter for letter in 'shark']
print(shark_letters)

ここでは、新しいリストが変数shark_lettersに割り当てられ、letterは、反復可能な文字列'shark'に含まれるアイテムの代わりに使用されます。

新しいリストshark_lettersがどのように見えるかを確認するために、print()を呼び出して、次の出力を受け取ります。

Output['s', 'h', 'a', 'r', 'k']

リスト内包表記で作成したリストは、文字列'shark'の項目で構成されています。つまり、文字ごとに1つの文字列です。

リスト内包表記はforループとして書き換えることができますが、すべてのforループをリスト内包表記として書き換えることができるわけではありません。

上記のshark_lettersリストを作成したリスト内包表記を使用して、forループとして書き直してみましょう。 これは、リストの理解がどのように機能するかをよりよく理解するのに役立ちます。

shark_letters = []

for letter in 'shark':
    shark_letters.append(letter)

print(shark_letters)

forループを使用してリストを作成する場合、リストに割り当てられた変数は、コードブロックの最初の行にあるため、空のリストで初期化する必要があります。 次に、forループは、反復可能な文字列'shark'の変数letterを使用して、アイテムを反復処理します。 forループ内では、文字列内の各項目はadded to the list with the list.append(x) methodです。

リスト内包表記をforループとして書き直すと、同じ出力が得られます。

Output['s', 'h', 'a', 'r', 'k']

リスト内包表記はforループとして書き直すことができ、一部のforループは、コードをより簡潔にするためにリスト内包表記として書き直すことができます。

リスト内包表記で条件を使用する

リストの内包表記では、条件付きステートメントを使用して、新しいリストを作成するときに既存のリストまたは他の順次データ型を変更できます。

リスト内包表記で使用されるifステートメントの例を見てみましょう。

fish_tuple = ('blowfish', 'clownfish', 'catfish', 'octopus')

fish_list = [fish for fish in fish_tuple if fish != 'octopus']
print(fish_list)

リスト内包表記は、fish_listと呼ばれる新しいリストの基礎としてタプルfish_tupleを使用します。 section aboveと同様に、forおよびinのキーワードが使用され、ifステートメントが追加されました。 ifステートメントは、文字列'octopus'と同等ではないアイテムのみを追加するように指示しているため、新しいリストは、'octopus'と一致しないタプルからのアイテムのみを取り込みます。

これを実行すると、文字列'octopus'が省略されていることを除いて、fish_listfish_tupleと同じ文字列項目が含まれていることがわかります。

Output['blowfish', 'clownfish', 'catfish']

したがって、新しいリストには、条件ステートメントによって除外される文字列を除く、元のタプルのすべての項目が含まれます。

mathematical operatorsintegers、およびrange() sequence typeを使用する別の例を作成します。

number_list = [x ** 2 for x in range(10) if x % 2 == 0]
print(number_list)

作成中のリストnumber_listには、0〜9ifの範囲の各アイテムの2乗値が入力され、アイテムの値は2で割り切れます。 出力は次のとおりです。

Output[0, 4, 16, 36, 64]

リスト内包表記が行っていることをもう少し詳しく説明するために、x for x in range(10)を呼び出しただけで何が出力されるかを考えてみましょう。 小さなプログラムと出力は次のようになります。

number_list = [x for x in range(10)]
print(number_list)
Output[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

それでは、条件ステートメントを追加しましょう。

number_list = [x for x in range(10) if x % 2 == 0]
print(number_list)
Output[0, 2, 4, 6, 8]

ifステートメントは、最終リストの項目を2で割り切れる項目のみを含むように制限し、奇数をすべて省略しました。

最後に、各xを2乗する演算子を追加できます。

number_list = [x ** 2 for x in range(10) if x % 2 == 0]
print(number_list)

したがって、[0, 2, 4, 6, 8]の前のリストの各数値は、2乗されます。

Output[0, 4, 16, 36, 64]

リスト内包表記を使用してnested if statementsを複製することもできます。

number_list = [x for x in range(100) if x % 3 == 0 if x % 5 == 0]
print(number_list)

ここで、リスト内包表記は、最初に数値xが3で割り切れるかどうかを確認し、次にxが5で割り切れるかどうかを確認します。 xが両方の要件を満たしている場合、出力され、出力は次のようになります。

Output[0, 15, 30, 45, 60, 75, 90]

条件付きifステートメントを使用して、既存のシーケンスのどのアイテムを新しいリストの作成に含めるかを制御できます。

リスト内包の入れ子ループ

Nested loopsを使用して、プログラムで複数の反復を実行できます。

今回は、既存のネストされたforループ構造を見て、リスト内包に向けて作業します。

コードは、2つのリストを反復処理し、それらに基づいて数学演算を実行する新しいリストを作成します。 ネストされたforループコードブロックは次のとおりです。

my_list = []

for x in [20, 40, 60]:
    for y in [2, 4, 6]:
        my_list.append(x * y)

print(my_list)

このコードを実行すると、次の出力が表示されます。

Output[40, 80, 120, 80, 160, 240, 120, 240, 360]

このコードは、反復ごとに最初のリストのアイテムに2番目のリストのアイテムを乗算しています。

これをリスト内包表記に変換するために、x * y演算から始めて、コードの各行を1行に要約します。 この後に、外側のforループ、次に内側のforループが続きます。 リスト内包表記の下にprint()ステートメントを追加して、新しいリストが上記のネストされたforループブロックで作成したリストと一致することを確認します。

my_list = [x * y for x in [20, 40, 60] for y in [2, 4, 6]]
print(my_list)
Output[40, 80, 120, 80, 160, 240, 120, 240, 360]

リスト内包表記は、ネストされたforループを取得し、それらを1行のコードにフラット化すると同時に、my_list変数に割り当てるまったく同じリストを作成します。

リストの内包表記により、リストを作成する簡潔な方法が提供され、数行のコードを1行に変換できます。 ただし、コードの可読性は常に優先される必要があるため、リストの理解の行が長すぎるか扱いにくい場合は、ループに分割することをお勧めします。

結論

リストの内包表記により、1つのリストまたは他のシーケンスを新しいリストに変換できます。 これらは、このタスクを完了するための簡潔な構文を提供し、コードの行を制限します。

リスト内包表記は、セットビルダー表記法またはセット内包表記の数学的形式に従うため、数学的な背景を持つプログラマーにとって特に直感的です。

リストを理解するとコードが簡潔になりますが、最終的なコードをできるだけ読みやすくすることが重要です。そのため、コードがユーザーフレンドリであることを保証するために、非常に長いコード行を避ける必要があります。