- Python
Pythonジェネレータとyield|使い所とメモリ比較コード集
Pythonのジェネレータとは、yield を使って値を1つずつ作りながら返す関数(またはその戻り値のオブジェクト)です。 すべての値をリストに入れてから返すのではなく、「必要になった分だけその場で作る」ため、大量のデータでもメモリをほとんど使わずに処理できます。
この記事では、まずイテレータ・ジェネレータ関数・ジェネレータ式の関係を早見表で整理します。次に、リストとのメモリ差を sys.getsizeof と tracemalloc で実測し、200万行(87MB)のログファイルを1行ずつ処理するパイプラインを組みます。さらに itertools との組み合わせ、yield from、send・throw・close、return の値の受け取り方、つまずきやすい点をすべて実行結果つきで解説し、非同期ジェネレータと contextlib.contextmanager との関係まで紹介します。
検証環境:Linux、Python 3.14.7(比較用に Python 3.11.15)。
ジェネレータの早見表
| 用語 | 正体 | 作り方 | 何度も回せるか |
|---|---|---|---|
| イテラブル | for で回せるもの |
list、dict、str、ファイル、__iter__ を持つクラス |
○(リスト等) |
| イテレータ | next() で次の値を返すもの |
iter(イテラブル) |
×(1回きり) |
| ジェネレータ関数 | 本体に yield を含む関数 |
def f(): yield ... |
— |
| ジェネレータ | ジェネレータ関数を呼んだ戻り値(イテレータの一種) | g = f() |
×(1回きり) |
| ジェネレータ式 | 1行で書くジェネレータ | (x * 2 for x in data) |
×(1回きり) |
| 非同期ジェネレータ | async def の中で yield |
async for で回す |
×(1回きり) |
| やりたいこと | 書き方 |
|---|---|
| 次の値を1つ取る | next(g)/next(g, 既定値) |
| 先頭n件だけ取る | itertools.islice(g, n) |
| 複数をつなげる | itertools.chain(a, b)/yield from a |
| n件ずつまとめる | itertools.batched(g, n)(3.12+) |
| 別のジェネレータに任せる | yield from sub() |
| 外から値を渡す | g.send(値)(最初は next(g)) |
| 中に例外を投げ込む | g.throw(例外) |
| 途中で終わらせる | g.close()(3.13+は return 値を返す) |
return の値を受け取る |
StopIteration.value/x = yield from sub() |
| 合計・最大・存在確認 | sum(...)・max(...)・any(...) にそのまま渡す |
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「Pythonジェネレータとyield|使い所とメモリ比較コード集」
イテレータとジェネレータの関係
ジェネレータは、イテレータを簡単に作るための仕組みです。 イテレータは __iter__ と __next__ を持ち、値がなくなると StopIteration を送出するオブジェクトです。ジェネレータ関数を呼ぶと、この2つを自動で備えたオブジェクトが返ります。
flowchart LR
A[イテラブル<br/>list・str・ファイル] -->|iter で取り出す| B[イテレータ<br/>__next__ を持つ]
C[ジェネレータ関数<br/>def ... yield] -->|呼び出す| D[ジェネレータ]
E[ジェネレータ式<br/>x for x in ...] --> D
D -->|イテレータの一種| B
yieldで一時停止する動きを確かめる
# basics.py(Python 3.8+)
from collections.abc import Iterator, Generator, Iterable
def count_up(n):
print(" 開始")
i = 1
while i <= n:
print(f" yield {i} の直前")
yield i
i += 1
print(" 終了")
g = count_up(2)
print(type(g).__name__, isinstance(g, Iterator), isinstance(g, Generator))
print("next →", next(g))
print("next →", next(g))
try:
next(g)
except StopIteration:
print("StopIteration")
print(iter(g) is g)
lst = [1, 2]
print(isinstance(lst, Iterable), isinstance(lst, Iterator), iter(lst) is lst)
実行結果(Python 3.14.7):
generator True True
開始
yield 1 の直前
next → 1
yield 2 の直前
next → 2
終了
StopIteration
True
True False False
count_up(2) を呼んだ時点では「開始」が表示されていない点に注目してください。本体は最初の next() で動き出し、yield で値を返して一時停止し、次の next() で続きから再開します。最後まで進むと StopIteration が送出され、for 文はこれを合図にループを終えます。
iter(g) is g が True なのは、ジェネレータが自分自身をイテレータとして返すからです。一方リストは iter() のたびに新しいイテレータを作るので、何度でも回せます。
クラスで書くイテレータとの比較
# iterclass.py
class Countdown: # イテレータをクラスで書く場合
def __init__(self, start):
self.n = start
def __iter__(self):
return self
def __next__(self):
if self.n <= 0:
raise StopIteration
self.n -= 1
return self.n + 1
def countdown(start): # 同じものをジェネレータ関数で
while start > 0:
yield start
start -= 1
class Inventory: # 何度でも回せるイテラブル
def __init__(self, items):
self.items = items
def __iter__(self): # __iter__ をジェネレータにする
for name in self.items:
yield name
print(list(Countdown(3)), list(countdown(3)))
inv = Inventory(["ペン", "ノート"])
print(list(inv), list(inv))
[3, 2, 1] [3, 2, 1]
['ペン', 'ノート'] ['ペン', 'ノート']
クラスで12行かかるイテレータが、ジェネレータ関数なら4行で書けます。また、__iter__ をジェネレータにすると、何度でも回せるクラスになります(回すたびに新しいジェネレータが作られるため)。
ジェネレータ関数とジェネレータ式の使い分け
| 比べる点 | ジェネレータ関数 | ジェネレータ式 |
|---|---|---|
| 書き方 | def f(): ... yield x |
(式 for x in ... if ...) |
| 複数行の処理・try・with | 書ける | 書けない |
| 状態(合計・前の値)を持つ | 得意 | 不向き |
send・return の値 |
使える | 使わない |
| 向いている場面 | ファイル読み込み、パイプラインの各段 | sum・max・any に渡す一時的な計算 |
ジェネレータ式の書き方は、別記事「Python内包表記」で早見表にまとめています。
リストとのメモリ比較(実測)
100万個の値を、リストは約8MB(中身を含めると約39MB)使い、ジェネレータは約200バイトで済みました。
# mem.py(Python 3.8+)
import sys, tracemalloc
N = 1_000_000
def squares_list(n):
return [i * i for i in range(n)]
def squares_gen(n):
for i in range(n):
yield i * i
print("getsizeof リスト :", f"{sys.getsizeof(squares_list(N)):,} バイト")
print("getsizeof ジェネレータ:", f"{sys.getsizeof(squares_gen(N)):,} バイト")
for label, make in [("リスト", squares_list), ("ジェネレータ", squares_gen)]:
tracemalloc.start()
total = sum(make(N))
current, peak = tracemalloc.get_traced_memory()
tracemalloc.stop()
print(f"{label:<8} sum={total} ピーク {peak / 1024:10,.1f} KiB")
実行結果(Python 3.14.7。3.11.15でも同じ値でした):
getsizeof リスト : 8,448,728 バイト
getsizeof ジェネレータ: 208 バイト
リスト sum=333332833333500000 ピーク 39,497.1 KiB
ジェネレータ sum=333332833333500000 ピーク 0.2 KiB
| 測り方 | 何を測るか | リスト | ジェネレータ |
|---|---|---|---|
sys.getsizeof |
オブジェクト本体だけ(リストは要素への参照の配列) | 約8.4MB | 208バイト |
tracemalloc のピーク |
処理中にPythonが確保したメモリの最大値(要素の整数も含む) | 約38.6MiB | 約0.2KiB |
sys.getsizeof は中身の大きさを含まないため、実際のメモリ使用量を見たいときは tracemalloc のピーク値を使うのが確実です。
大きなファイルを1行ずつ処理する
ファイルオブジェクトはそれ自体がイテレータなので、for line in f で1行ずつ読めます。 次のコードで作業用のログファイル(200万行、87MB)を作り、readlines() と比べました。
# make_log.py:作業用の大きなログファイルを作る
import random
random.seed(1)
levels = ["INFO"] * 8 + ["WARN", "ERROR"]
items = ["ノート", "ペン", "付箋", "ファイル", "テープ"]
with open("access.log", "w", encoding="utf-8") as f:
for i in range(2_000_000):
f.write(f"2026-09-30T{i % 24:02d}:{i % 60:02d}:00 {random.choice(levels)} "
f"item={random.choice(items)} qty={random.randint(1, 9)}\n")
$ ls -lh access.log
-rw-r--r-- 1 root root 87M Oct 1 23:09 access.log
$ head -3 access.log
2026-09-30T00:00:00 INFO item=テープ qty=2
2026-09-30T01:01:00 INFO item=ノート qty=8
2026-09-30T02:02:00 INFO item=ファイル qty=7
# bigfile.py
import time, tracemalloc
def run(label, fn):
tracemalloc.start()
t = time.perf_counter()
result = fn()
sec = time.perf_counter() - t
_, peak = tracemalloc.get_traced_memory()
tracemalloc.stop()
print(f"{label:<22} 結果={result:,} {sec:5.2f} 秒 ピーク {peak / 1024 / 1024:7.2f} MiB")
def with_readlines():
with open("access.log", encoding="utf-8") as f:
lines = f.readlines() # 全行をリストに読み込む
return sum(1 for line in lines if " ERROR " in line)
def with_iteration():
with open("access.log", encoding="utf-8") as f:
return sum(1 for line in f if " ERROR " in line) # 1行ずつ読む
run("readlines()(全行)", with_readlines)
run("for line in f(1行ずつ)", with_iteration)
実行結果(Python 3.14.7):
readlines()(全行) 結果=200,435 1.72 秒 ピーク 279.31 MiB
for line in f(1行ずつ) 結果=200,435 1.07 秒 ピーク 0.17 MiB
同じ結果を、ピークメモリ約279MiB→約0.17MiBで得られました。 ファイルが大きくなっても、1行ずつ読む方式ならメモリ使用量はほぼ一定です。
パイプラインを組む(読み込み→フィルタ→変換→集計)
ジェネレータをつなげると、各段が1行ずつ受け渡しながら動くパイプラインになります。 それぞれの関数は短く、単体でテストしやすいのも利点です。
# pipeline.py(Python 3.9+:str.removeprefix を使用)
import time, tracemalloc
from collections import Counter
from itertools import islice
def read_lines(path): # 1. 読み込み
with open(path, encoding="utf-8") as f:
for line in f:
yield line.rstrip("\n")
def only_errors(lines): # 2. フィルタ
for line in lines:
if " ERROR " in line:
yield line
def parse(lines): # 3. 変換
for line in lines:
_, _, item, qty = line.split(" ")
yield item.removeprefix("item="), int(qty.removeprefix("qty="))
def total_by_item(records): # 4. 集計
c = Counter()
for item, qty in records:
c[item] += qty
return c
tracemalloc.start()
t = time.perf_counter()
print("先頭3件:", list(islice(parse(only_errors(read_lines("access.log"))), 3)))
result = total_by_item(parse(only_errors(read_lines("access.log"))))
_, peak = tracemalloc.get_traced_memory()
print(dict(result.most_common()))
print(f"{time.perf_counter() - t:.2f} 秒 ピーク {peak / 1024:.1f} KiB")
実行結果(Python 3.14.7):
先頭3件: [('ノート', 8), ('テープ', 7), ('付箋', 8)]
{'ペン': 201461, 'ノート': 201415, '付箋': 200967, 'テープ': 200838, 'ファイル': 200516}
2.50 秒 ピーク 171.9 KiB
flowchart LR
A[read_lines<br/>1行読む] -->|1行| B[only_errors<br/>ERRORだけ通す]
B -->|1行| C[parse<br/>品名と数量に分解]
C -->|1件| D[total_by_item<br/>Counterで合計]
87MBのファイル全体を処理しても、ピークは約172KiBでした。 islice で先頭3件だけ取り出すと、残りの行は読まれません。動作確認のときに便利です。
itertoolsと組み合わせる
itertools の関数はどれもイテレータを受け取ってイテレータを返すので、ジェネレータと自然につながります。
# itertools_demo.py(batched は 3.12+、strict は 3.13+)
from itertools import islice, chain, batched, count, takewhile
def order_ids():
n = 1000
while True: # 無限に続くジェネレータ
yield f"ORD-{n}"
n += 1
print(list(islice(order_ids(), 3)))
print(list(islice(order_ids(), 5, 8)))
print(list(chain(["ペン", "ノート"], (s for s in ["付箋"]))))
for batch in batched(islice(order_ids(), 7), 3):
print("まとめて登録:", batch)
print(list(takewhile(lambda x: x < 20, (n * n for n in count(1)))))
try:
list(batched(range(7), 3, strict=True))
except ValueError as e:
print("ValueError:", e)
実行結果(Python 3.14.7):
['ORD-1000', 'ORD-1001', 'ORD-1002']
['ORD-1005', 'ORD-1006', 'ORD-1007']
['ペン', 'ノート', '付箋']
まとめて登録: ('ORD-1000', 'ORD-1001', 'ORD-1002')
まとめて登録: ('ORD-1003', 'ORD-1004', 'ORD-1005')
まとめて登録: ('ORD-1006',)
[1, 4, 9, 16]
ValueError: batched(): incomplete batch
| 関数 | 役割 | 対応版 |
|---|---|---|
islice(it, n)/islice(it, start, stop) |
先頭n件・範囲を取る(スライスの代わり) | 全版 |
chain(a, b, ...) |
複数をつなげる | 全版 |
batched(it, n) |
n件ずつタプルにまとめる(DBへのまとめて登録など) | 3.12+(strict は3.13+) |
count(start) |
無限に数える | 全版 |
takewhile(条件, it) |
条件を満たす間だけ取る | 全版 |
tee(it, n) |
1つのイテレータをn本に分ける | 全版 |
Python 3.11で batched を使うと ImportError: cannot import name 'batched' from 'itertools' になります。3.11以前では islice を使って同じ動きを書けます。
from itertools import islice
def batched_compat(iterable, n): # 3.11以前向け
it = iter(iterable)
while batch := tuple(islice(it, n)):
yield batch
yield fromで別のジェネレータに任せる
yield from イテラブル は、中身を1つずつ yield するのと同じ動きをし、さらにサブジェネレータの return の値を受け取れます。
# yieldfrom.py(Python 3.8+)
def categories():
yield from ["文具", "収納"] # イテラブルをそのまま流す
yield from sub_items()
def sub_items():
yield "ペン"
yield "ノート"
return "sub完了" # return の値
def outer():
result = yield from sub_items() # サブジェネレータの return 値を受け取る
print(" 受け取った値:", result)
print(list(categories()))
print(list(outer()))
g = sub_items()
next(g); next(g)
try:
next(g)
except StopIteration as e:
print("StopIteration.value =", e.value)
def walk(tree): # 入れ子の構造を平らにする
for node in tree:
if isinstance(node, list):
yield from walk(node)
else:
yield node
print(list(walk(["A", ["B", ["C", "D"]], "E"])))
実行結果(Python 3.14.7):
['文具', '収納', 'ペン', 'ノート']
受け取った値: sub完了
['ペン', 'ノート']
StopIteration.value = sub完了
['A', 'B', 'C', 'D', 'E']
ジェネレータ内の return 値 は、StopIteration.value として外に渡されます。 for 文や list() はこの値を使わないので、受け取りたいときは yield from の戻り値か、next() と except StopIteration as e を使います。yield from は send・throw もサブジェネレータにそのまま中継します。
send・throw・closeで外から操作する
send(値) は yield 式の戻り値として値を渡しながら再開し、throw(例外) は止まっている yield の位置で例外を発生させ、close() は終了させます。
# send.py
def running_average():
total, count, avg = 0, 0, None
while True:
value = yield avg # send() で受け取った値が入る
total += value
count += 1
avg = total / count
avg = running_average()
print(next(avg)) # 最初の yield まで進める
print(avg.send(10))
print(avg.send(20))
print(avg.send(60))
g = running_average()
try:
g.send(10)
except TypeError as e:
print("TypeError:", e)
def worker():
try:
while True:
try:
task = yield
print(" 処理:", task)
except ValueError as e:
print(" throw で受け取った:", e)
finally:
print(" 後片付け(finally)")
w = worker()
next(w)
w.send("在庫チェック")
w.throw(ValueError("入力が不正です"))
w.send("棚卸し")
w.close()
print("close 後の状態:", w.gi_frame is None)
def counter():
n = 0
try:
while True:
yield
n += 1
except GeneratorExit:
return n # 3.13+ では close() がこの値を返す
c = counter()
next(c); next(c); next(c)
print("close() の戻り値:", c.close())
実行結果(Python 3.14.7):
None
10.0
15.0
30.0
TypeError: can't send non-None value to a just-started generator
処理: 在庫チェック
throw で受け取った: 入力が不正です
処理: 棚卸し
後片付け(finally)
close 後の状態: True
close() の戻り値: 2
Python 3.11.15では最後の行が close() の戻り値: None でした。3.13から、GeneratorExit を受けて return した値を close() が返すようになっています。
| メソッド | 動き | よくある使い方 |
|---|---|---|
next(g) |
次の yield まで進める(send(None) と同じ) |
値を取り出す、最初の起動 |
g.send(値) |
yield 式の結果として値を渡して再開 |
移動平均などの状態を持つ計算 |
g.throw(例外) |
止まっている yield の位置で例外を発生 |
中断の合図、エラーの通知 |
g.close() |
GeneratorExit を発生させて終了 |
途中でやめるときの後片付け |
最初の send の前に next(g)(または g.send(None))が必要です。忘れると上のとおり TypeError: can't send non-None value to a just-started generator になります。
つまずきやすいポイント
一度しか回せない・len()や添字が使えない
# pitfalls.py
def items():
yield "ペン"
yield "ノート"
g = items()
print("1回目:", list(g))
print("2回目:", list(g))
print("in 演算子:", "ペン" in items(), "ペン" in g)
try:
len(items())
except TypeError as e:
print("TypeError:", e)
try:
items()[0]
except TypeError as e:
print("TypeError:", e)
1回目: ['ペン', 'ノート']
2回目: []
in 演算子: True False
TypeError: object of type 'generator' has no len()
TypeError: 'generator' object is not subscriptable
使い切ったジェネレータはエラーにならず空を返すので、2回目の結果が空のときはここを疑います。何度も使うなら list() にするか、ジェネレータ関数を呼び直します。件数が必要なら sum(1 for _ in g)、先頭の値なら next(g) を使います。in 演算子も、見つかるまで値を消費する点に注意します。
例外の伝わり方
def broken():
yield 1
raise StopIteration # ジェネレータの中で StopIteration を送出
try:
list(broken())
except RuntimeError as e:
print("RuntimeError:", e)
def lazy_check(values):
if not values:
raise ValueError("空です") # 呼び出した時点では実行されない
yield from values
g = lazy_check([])
print("ジェネレータは作れた:", type(g).__name__)
try:
next(g)
except ValueError as e:
print("next() で初めて ValueError:", e)
def parse_qty(rows):
for r in rows:
yield int(r)
gen = parse_qty(["1", "x", "3"])
print(next(gen))
try:
next(gen)
except ValueError as e:
print("ValueError:", e)
print("例外のあと:", list(gen))
RuntimeError: generator raised StopIteration
ジェネレータは作れた: generator
next() で初めて ValueError: 空です
1
ValueError: invalid literal for int() with base 10: 'x'
例外のあと: []
| 現象 | 理由 | 対処 |
|---|---|---|
RuntimeError: generator raised StopIteration |
ジェネレータ内の StopIteration は RuntimeError に置き換わる(PEP 479) |
終わりたいときは return と書く |
| 引数チェックのエラーが遅れて出る | 本体は最初の next() まで動かない |
チェックを普通の関数に分け、中でジェネレータを返す |
| 例外のあと残りが取れない | 例外が外に出たジェネレータは終了する | 1件の失敗で止めたくないなら、ジェネレータ内で try/except して印をつけて yield |
引数チェックをすぐに行いたい場合は、次のように分けます。
def lazy_check(values):
if not values:
raise ValueError("空です") # 呼んだ瞬間にチェックされる
return _iter_values(values)
def _iter_values(values):
yield from values
with の外で回すとファイルが閉じている
def lines_wrong(path):
with open(path, encoding="utf-8") as f:
return (line for line in f) # ジェネレータ式を返した時点で with を抜ける
この関数の戻り値を回すと ValueError: I/O operation on closed file. になります。with の中で yield する(上の read_lines のように書く)と、最後まで読み終えるかジェネレータが閉じられるまでファイルが開いたままになります。
非同期ジェネレータの最小例
async def の中で yield を使うと非同期ジェネレータになり、async for で回します。 ページごとにAPIを呼ぶような、待ち時間をはさみながら値を順に返す処理に向いています。
# agen.py(Python 3.8+)
import asyncio
async def fetch_pages(n):
for page in range(1, n + 1):
await asyncio.sleep(0.1) # API呼び出しの待ち時間の代わり
yield {"page": page, "items": page * 10}
async def main():
async for p in fetch_pages(3):
print(p)
print([p["items"] async for p in fetch_pages(2)])
asyncio.run(main())
実行結果(Python 3.14.7):
{'page': 1, 'items': 10}
{'page': 2, 'items': 20}
{'page': 3, 'items': 30}
[10, 20]
非同期ジェネレータでは yield from は使えないため、async for x in sub(): yield x と書きます。asyncioそのものの書き方は、別記事「Python asyncioの使い方」で解説しています。
contextlib.contextmanagerとの関係
@contextmanager は、yield が1回だけのジェネレータ関数を with 文で使えるようにするデコレータです。 yield の前が with に入るときの処理、後が出るときの処理になり、yield した値が as の変数に入ります。
# ctx.py(Python 3.8+)
import time
from contextlib import contextmanager
@contextmanager
def timer(label):
start = time.perf_counter()
print(f"[{label}] 開始")
try:
yield start # with ... as の値になる
finally:
print(f"[{label}] 終了 {time.perf_counter() - start:.2f} 秒")
with timer("棚卸し") as t0:
time.sleep(0.1)
try:
with timer("エラー時"):
raise KeyError("備品ID")
except KeyError as e:
print("例外は外に伝わる:", e)
実行結果(Python 3.14.7):
[棚卸し] 開始
[棚卸し] 終了 0.10 秒
[エラー時] 開始
[エラー時] 終了 0.00 秒
例外は外に伝わる: '備品ID'
with ブロック内の例外は、yield の位置に投げ込まれます(内部で throw() が使われています)。そのため、後片付けを確実に行うには yield を try/finally で囲みます。
ジェネレータを使うか、リストにするかの判断表
| 状況 | おすすめ | 理由 |
|---|---|---|
| 大きなファイル・DBの結果を順に処理 | ジェネレータ | メモリがほぼ一定 |
| 結果を1回だけ順に使う | ジェネレータ | リストを作る手間が不要 |
| 無限に続く値(連番、ポーリング) | ジェネレータ | リストでは表せない |
| 件数・添字・並べ替えが必要 | リスト | len・[i]・sort が使える |
| 同じ結果を何度も使う | リスト | ジェネレータは1回きり |
| 少量のデータで手軽に確認 | リスト | 表示やデバッグがしやすい |
よくある質問
Q. yieldとreturnの違いは何ですか?
A. return は値を返して関数を終わらせ、yield は値を返して一時停止します。 ジェネレータ関数の中の return 値 は、StopIteration.value として渡される「終わりの合図」になります。
Q. ジェネレータの中身を確認したいときは?
A. list(g) で中身を表示できますが、その時点で使い切ります。list(itertools.islice(g, 5)) で先頭だけ確認し、本番の処理には新しく作り直したジェネレータを渡すと安全です。
Q. ジェネレータはリストより遅いですか?
A. 今回の87MBのファイルでは、1行ずつ読むほうが1.07秒、readlines() が1.72秒でした。少量で何度も使う場合はリスト、大量・1回きりならジェネレータを目安にするとよいでしょう。
Q. 型ヒントはどう書きますか?
A. 値を返すだけなら Iterator[int]、send・return も使うなら Generator[int, float, str](yieldする型、sendする型、returnする型)と書きます。3.13以降は後ろ2つに既定値(None)があり、Generator[int] と書けます。
まとめ
- ジェネレータは
yieldで値を1つずつ返すイテレータ。呼んだ時点では本体は動かず、next()で進みます。 - 実測では100万件でリスト約38.6MiB→ジェネレータ約0.2KiB、87MBのファイルもピーク約0.17MiBで処理できました。
- 読み込み→フィルタ→変換→集計をジェネレータでつなぐと、短い関数の組み合わせで大量データを扱えます。
islice・chain・batched(3.12+) と組み合わせると、先頭だけ・連結・まとめて処理が1行で書けます。yield fromは委譲とreturn値の受け取り、send・throw・closeは外からの操作に使います(3.13+はclose()が値を返します)。- 一度しか回せない・
len()が使えない・エラーは最初のnext()で出る、の3点を押さえておくと迷いません。
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「Pythonジェネレータとyield|使い所とメモリ比較コード集」
株式会社RJCでは、Pythonのジェネレータを使ったデータ処理を仲間と学び合っています。こうした知識を共有しながら、日々技術を磨いています。
株式会社RJC ― SI事業・SES事業・AI駆動開発。RJCは一緒に成長を楽しめる会社です。
WE ARE HIRING
RJCで一緒に開発しながら、
成長を楽しみませんか?
RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!
- 127日年間休日
- 12時間平均残業時間
- 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!
ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。