0Pricing
Python Academy · レッスン

ジェネレータ式

簡潔な遅延パイプラインを記述します

「ジェネレータ式」はCoddyKit上の無料Python Academyレッスンです。 これはレッスン3/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはPython Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Python Academyコースには全4レッスンが含まれています。

リスト内包表記からジェネレーター式へ

ジェネレーター式はリスト内包表記に似ていますが、角括弧の代わりに丸括弧を使います。完全なリストを構築するのではなく、値を遅延評価で生成します。

list_comp = [x * x for x in range(5)]
gen_expr = (x * x for x in range(5))
print(list_comp)
print(gen_expr)
print(list(gen_expr))

メモリ使用量の違い

リスト内包表記は、すべての要素をあらかじめ確保します。ジェネレーター式は、値を要求するまでほとんど何も保持しません。それぞれのサイズを比較してみましょう。

import sys
lst = [x for x in range(10000)]
gen = (x for x in range(10000))
print('list bytes:', sys.getsizeof(lst))
print('gen bytes:', sys.getsizeof(gen))

ジェネレーター式を反復する

ジェネレーター式は、他のイテレーターと同じように消費します。forループやnext()を使うか、関数に渡します。

gen = (c.upper() for c in 'hello')
for ch in gen:
    print(ch)

ifによるフィルタリング

内包表記と同じように、if節を追加して条件に一致する項目だけを残します。

evens = (n for n in range(10) if n % 2 == 0)
print(list(evens))

関数に直接渡す

ジェネレーター式が関数の唯一の引数である場合は、余分な丸括弧を省略できます。これによりコードがすっきりし、一時的なリストの構築も避けられます。

total = sum(x * x for x in range(5))
print(total)
biggest = max(len(w) for w in ['a', 'abc', 'ab'])
print(biggest)

一度しか使えないことを再確認

ジェネレーター式は、ジェネレーター関数と同じように、一度反復すると使い切られます。2回目の反復では何も生成されません。

gen = (x for x in range(3))
print(list(gen))
print(list(gen))

式の連結

あるジェネレーター式を別のジェネレーター式に渡して、遅延評価されるパイプラインを構築できます。最終的な消費側が値を要求するまで、何も計算されません。

nums = (n for n in range(10))
evens = (n for n in nums if n % 2 == 0)
doubled = (n * 2 for n in evens)
print(list(doubled))

any()とall()

ジェネレーター式はany()やall()と組み合わせると効果を発揮します。これらは短絡評価できるため、答えがわかった時点ですぐに処理を停止できます。

words = ['cat', 'dog', 'elephant']
print(any(len(w) > 5 for w in words))
print(all(len(w) >= 3 for w in words))

ネストしたループ

内包表記と同じように、ジェネレーター式では複数のfor節を左から右へ記述できます。

pairs = ((x, y) for x in range(2) for y in range(2))
print(list(pairs))

遅延評価パイプラインの例

ここでは、簡単なテキスト処理パイプラインを示します。各段階が遅延評価されるため、巨大なファイルでもすべてを読み込まずにストリーム処理できます。

lines = ['  alpha ', '', '  beta', 'gamma  ']
stripped = (line.strip() for line in lines)
nonempty = (line for line in stripped if line)
print(list(nonempty))

どちらを選ぶべきか

データを複数回使う場合やインデックスが必要な場合はリスト内包表記を使用します。1回だけのストリーム処理や大規模なデータにはジェネレーター式を使用します。

data = range(6)
as_list = [x + 1 for x in data]
print(as_list[0], as_list[-1])
total = sum(x + 1 for x in data)
print(total)

理解度チェック

ジェネレーター式の理解度を確認しましょう。

まとめ

ジェネレーター式について学びました。

  • リスト内包表記の遅延評価版として、丸括弧を使います。
  • メモリを節約でき、ifによるフィルターやネストしたループにも対応しています。
  • sum、any、all、連結処理と相性がよいです。
  • 一度しか使用できません。

次は、yield fromを使ったジェネレーターの組み合わせ方を学びます。

よくある質問

「ジェネレータ式」レッスンは無料ですか?

はい。「ジェネレータ式」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Python Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Python Academyコースには全4レッスンが含まれています。

「ジェネレータ式」で何を学びますか?

簡潔な遅延パイプラインを記述します ブラウザで直接実行するハンズオンコードでPython Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

Python Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのPython Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン3/4です。

「ジェネレータ式」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このPython Academyレッスンでコードを書いて実行できますか?

はい。すべてのPython Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. イテレータプロトコル
  2. ジェネレータ関数
  3. ジェネレータ式
  4. yield fromと委譲
← Python Academyに戻る