Pythonコードをより簡潔に、効率的に書くための強力なテクニックを学びます。
1. リスト内包表記って何? 🤔
リスト内包表記(List Comprehension)は、既存のリストや他のイテラブル(繰り返し可能なオブジェクト、例えば文字列やrangeなど)から、新しいリストを効率的に作成するためのPythonの構文です。
従来のfor
ループを使った方法よりも、コードを短く、そして多くの場合読みやすく書くことができます✨。
前回学んだリスト、タプル、辞書、セットといったコレクション操作の延長線上にある、非常に便利な機能です。これを使いこなせると、Pythonプログラミングがさらに楽しくなりますよ!
2. 基本的な使い方
まずは、簡単な例を見てみましょう。0から9までの数値の二乗を要素とするリストを作成します。
従来のforループを使った場合
squares = []
for i in range(10):
squares.append(i * i)
print(squares)
# 出力: [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
リスト内包表記を使った場合
同じ処理をリスト内包表記で書くと、次のようになります。
squares = [i * i for i in range(10)]
print(squares)
# 出力: [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
どうでしょうか?たった1行で同じ結果が得られ、コードがスッキリしましたね!🎉
構文
リスト内包表記の基本的な構文は以下の通りです。
[式 for 要素 in イテラブルオブジェクト]
- 式: 新しいリストの各要素となる値や処理を記述します。上の例では
i * i
です。 - 要素: イテラブルオブジェクトから取り出される各要素を格納する変数名です。上の例では
i
です。 - イテラブルオブジェクト:
for
ループで処理する対象となるリスト、タプル、文字列、range
オブジェクトなどです。上の例ではrange(10)
です。
他の例
文字列のリストから、各文字列の長さを要素とするリストを作成してみましょう。
words = ["apple", "banana", "cherry"]
lengths = [len(word) for word in words]
print(lengths)
# 出力: [5, 6, 6]
3. 条件分岐 (if) との組み合わせ
リスト内包表記では、if
文を使って、特定の条件を満たす要素だけを新しいリストに含めることができます。フィルタリング処理を簡単に追加できるのです。
構文
if
条件を加えた構文は以下のようになります。
[式 for 要素 in イテラブルオブジェクト if 条件式]
for
ループの後ろにif
と条件式を追加します。この条件式が真 (True) となる要素だけが、式の処理対象となり、新しいリストに含まれます。
例:偶数のみを取り出す
0から9までの数値の中から、偶数だけを取り出してリストを作成します。
even_numbers = [i for i in range(10) if i % 2 == 0]
print(even_numbers)
# 出力: [0, 2, 4, 6, 8]
例:特定の文字で始まる文字列のみを取り出す
fruits = ["apple", "banana", "apricot", "blueberry", "avocado"]
a_fruits = [fruit for fruit in fruits if fruit.startswith("a")]
print(a_fruits)
# 出力: ['apple', 'apricot', 'avocado']
if
を使ったフィルタリングは、要素を含めるかどうかを判断します。もし条件によって処理内容を変えたい場合(例:偶数ならそのまま、奇数なら二乗するなど)は、if-else
を式の部分に記述する三項演算子を使います (少し応用的な内容です)。例:
[x if x % 2 == 0 else x * x for x in range(10)]
4. forループのネスト
リスト内包表記では、for
ループを複数ネストさせることも可能です。これにより、複数のリストやイテラブルの組み合わせから新しいリストを作成できます。
構文
for
ループをネストする場合の構文は以下のようになります。
[式 for 要素1 in イテラブル1 for 要素2 in イテラブル2 ...]
for
句は書いた順に、外側から内側へとループ処理が行われます。
例:2つのリストの要素の組み合わせ
list1 = [1, 2]
list2 = ['a', 'b']
combinations = [(x, y) for x in list1 for y in list2]
print(combinations)
# 出力: [(1, 'a'), (1, 'b'), (2, 'a'), (2, 'b')]
# これは以下のforループと同じ意味です
# combinations = []
# for x in list1:
# for y in list2:
# combinations.append((x, y))
例:行列(リストのリスト)をフラットなリストに変換
matrix = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]
flattened = [num for row in matrix for num in row]
print(flattened)
# 出力: [1, 2, 3, 4, 5, 6, 7, 8, 9]
for
ループのネストは強力ですが、3つ以上ネストさせるとコードが非常に読みにくくなることがあります。複雑になりすぎる場合は、通常のfor
ループを使った方が分かりやすい場合もあります。可読性を常に意識しましょう。5. リスト内包表記のメリット・デメリット
リスト内包表記は便利ですが、万能ではありません。メリットとデメリットを理解して使いこなしましょう。
メリット 👍 | デメリット 👎 |
---|---|
コードが簡潔になることが多い。 | 複雑な処理や条件分岐を詰め込みすぎると、かえって読みにくくなる。 |
多くの場合、通常のfor ループよりも実行速度が速い(内部で最適化されているため)。 | デバッグが少し難しい場合がある(一行に処理がまとまっているため、途中の状態を確認しにくい)。 |
Pythonらしい書き方とされることが多い。 | 初学者にとっては、最初は少し理解しにくいかもしれない。 |
使いどころのアドバイス:
比較的単純なリストの生成やフィルタリングには積極的にリスト内包表記を使い、処理が複雑になる場合は無理せず通常のfor
ループを使う、という使い分けがおすすめです😊。
6. 他の内包表記 (セット・辞書)
リスト内包表記と同じような考え方で、セット(集合)や辞書(ディクショナリ)を作成するための内包表記も存在します。
セット内包表記 (Set Comprehension)
中括弧 {}
を使い、重複しない要素を持つセットを生成します。
numbers = [1, 2, 2, 3, 4, 4, 5]
unique_squares = {x * x for x in numbers}
print(unique_squares)
# 出力: {1, 4, 9, 16, 25} # 重複が除去され、順序は保証されない
辞書内包表記 (Dictionary Comprehension)
中括弧 {}
を使い、キー: 値
のペアを指定して辞書を生成します。
words = ["apple", "banana", "cherry"]
word_lengths = {word: len(word) for word in words}
print(word_lengths)
# 出力: {'apple': 5, 'banana': 6, 'cherry': 6}
これらもリスト内包表記と同様に、コードを簡潔にするのに役立ちます。
まとめ 🚀
今回は、リスト内包表記について学びました。基本的な使い方から、if
を使ったフィルタリング、for
のネストまで、様々なテクニックを見てきましたね。
- リスト内包表記は、リストを効率的に生成するための簡潔な構文です。
[式 for 要素 in イテラブル]
が基本形です。if
を使って要素をフィルタリングできます:[式 for 要素 in イテラブル if 条件]
for
をネストさせることもできますが、可読性に注意しましょう。- セット内包表記
{式 for ...}
や辞書内包表記{キー: 値 for ...}
もあります。
リスト内包表記は、Pythonコードをよりエレガントで効率的にするための重要なツールです。ぜひ実際にコードを書いて、その便利さを体験してみてください!💪
次は、「関数の定義と呼び出し」について学びます。プログラムを部品化して再利用するための基本をマスターしましょう!
コメント