はじめに
このセクションでは、ジェネレータ式や itertools モジュールなど、ジェネレータに関連する追加のトピックを紹介します。
This tutorial is from open-source community. Access the source code
💡 このチュートリアルは英語版からAIによって翻訳されています。原文を確認するには、 ここをクリックしてください
このセクションでは、ジェネレータ式や itertools モジュールなど、ジェネレータに関連する追加のトピックを紹介します。
リスト内包表記のジェネレータ版です。
>>> a = [1,2,3,4]
>>> b = (2*x for x in a)
>>> b
<generator object at 0x58760>
>>> for i in b:
... print(i, end=' ')
...
2 4 6 8
>>>
リスト内包表記との違い
一般的な構文
(<式> for i in s if <条件>)
関数の引数としても使用できます。
sum(x*x for x in a)
任意の反復可能オブジェクトに適用できます。
>>> a = [1,2,3,4]
>>> b = (x*x for x in a)
>>> c = (-x for x in b)
>>> for i in c:
... print(i, end=' ')
...
-1 -4 -9 -16
>>>
ジェネレータ式の主な用途は、シーケンスに対して何らかの計算を行い、結果を一度だけ使用するコードにあります。たとえば、ファイルからすべてのコメントを取り除きます。
f = open('somefile.txt')
lines = (line for line in f if not line.startswith('#'))
for line in lines:
...
f.close()
ジェネレータを使用すると、コードが高速に実行され、メモリを少なく使用します。ストリームに適用されるフィルタのようなものです。
itertools
モジュールitertools
は、反復子/ジェネレータを助けるために設計されたさまざまな関数を備えたライブラリモジュールです。
itertools.chain(s1,s2)
itertools.count(n)
itertools.cycle(s)
itertools.dropwhile(predicate, s)
itertools.groupby(s)
itertools.ifilter(predicate, s)
itertools.imap(function, s1,... sN)
itertools.repeat(s, n)
itertools.tee(s, ncopies)
itertools.izip(s1,..., sN)
すべての関数は、データを反復的に処理します。さまざまな種類の反復パターンを実装しています。
PyCon '08 の Generator Tricks for Systems Programmers チュートリアルで詳細を確認できます。
前のエクササイズでは、ログファイルに書き込まれる行に追従し、それらを行のシーケンスに解析するコードをいくつか書きました。このエクササイズはそれに基づいてさらに構築されます。stocksim.py
がまだ実行されていることを確認してください。
ジェネレータ式は、リスト内包表記のジェネレータ版です。たとえば:
>>> nums = [1, 2, 3, 4, 5]
>>> squares = (x*x for x in nums)
>>> squares
<generator object <genexpr> at 0x109207e60>
>>> for n in squares:
... print(n)
...
1
4
9
16
25
リスト内包表記とは異なり、ジェネレータ式は一度だけ使用できます。したがって、別のforループを試すと、何も得られません:
>>> for n in squares:
... print(n)
...
>>>
ジェネレータ式は、時々関数の引数に置かれます。最初は少し奇妙に見えますが、この実験を試してみてください:
>>> nums = [1,2,3,4,5]
>>> sum([x*x for x in nums]) ## リスト内包表記
55
>>> sum(x*x for x in nums) ## ジェネレータ式
55
>>>
上記の例では、大きなリストを操作している場合、ジェネレータを使用した2番目のバージョンがはるかに少ないメモリを使用します。
あなたの portfolio.py
ファイルでは、リスト内包表記を含むいくつかの計算を行いました。これらをジェネレータ式に置き換えてみてください。
ジェネレータ式は、小さなジェネレータ関数の便利な代替手段となることがよくあります。たとえば、次のような関数を書く代わりに:
def filter_symbols(rows, names):
for row in rows:
if row['name'] in names:
yield row
次のようなコードを書くことができます:
rows = (row for row in rows if row['name'] in names)
ticker.py
プログラムを修正して、適切にジェネレータ式を使用するようにします。
おめでとうございます!あなたは More Generators の実験を完了しました。あなたのスキルを向上させるために、LabEx でさらに実験を行って練習してください。