発電機の理解は何をしますか?それはどのように機能しますか?それに関するチュートリアルが見つかりませんでした。
発電機の理解は何をしますか?それはどのように機能しますか?それに関するチュートリアルが見つかりませんでした。
回答:
リストの内包を理解していますか?その場合、ジェネレータ式はリスト内包のようなものですが、関心のあるすべての項目を見つけてリストにパックするのではなく、待機して、式から各項目を1つずつ生成します。
>>> my_list = [1, 3, 5, 9, 2, 6]
>>> filtered_list = [item for item in my_list if item > 3]
>>> print(filtered_list)
[5, 9, 6]
>>> len(filtered_list)
3
>>> # compare to generator expression
...
>>> filtered_gen = (item for item in my_list if item > 3)
>>> print(filtered_gen) # notice it's a generator object
<generator object <genexpr> at 0x7f2ad75f89e0>
>>> len(filtered_gen) # So technically, it has no length
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: object of type 'generator' has no len()
>>> # We extract each item out individually. We'll do it manually first.
...
>>> next(filtered_gen)
5
>>> next(filtered_gen)
9
>>> next(filtered_gen)
6
>>> next(filtered_gen) # Should be all out of items and give an error
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
>>> # Yup, the generator is spent. No values for you!
...
>>> # Let's prove it gives the same results as our list comprehension
...
>>> filtered_gen = (item for item in my_list if item > 3)
>>> gen_to_list = list(filtered_gen)
>>> print(gen_to_list)
[5, 9, 6]
>>> filtered_list == gen_to_list
True
>>>
ジェネレータ式は一度に1つのアイテムしか生成しないため、メモリ使用量を大幅に節約できます。ジェネレータ式は、一度に1つの項目を取得し、その項目に基づいて多くの計算を実行してから、次の項目に進む必要があるシナリオで最も意味があります。複数の値が必要な場合は、ジェネレータ式を使用して、一度にいくつかを取得することもできます。プログラムを進める前にすべての値が必要な場合は、代わりにリスト内包表記を使用してください。
next(...)
するのではなく、.__next__()
Pythonの3に
If you need more than one value, you can also use a generator expression and grab a few at a time
。この使用法の例を挙げていただけますか?ありがとう。
リスト/ジェネレーター内包は、既存のリスト/ジェネレーターから新しいリスト/ジェネレーターを作成するために使用できる構造です。
1から10までの各数値の二乗のリストを生成するとします。これはPythonで実行できます。
>>> [x**2 for x in range(1,11)]
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
ここでrange(1,11)
は、リストを生成します[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
が、range
関数はPython 3.0より前のジェネレータではないため、使用した構成はリスト内包です。
同じことを行うジェネレータを作成したい場合は、次のようにできます。
>>> (x**2 for x in xrange(1,11))
<generator object at 0x7f0a79273488>
ただし、Python 3ではrange
ジェネレーターであるため、結果は使用する構文(角括弧または丸括弧)にのみ依存します。
ジェネレータの理解は、特定の構造を持つジェネレータを作成する簡単な方法です。のgenerator
すべての偶数を1つずつ出力するが必要だとしますyour_list
。関数スタイルを使用して作成すると、次のようになります。
def allEvens( L ):
for number in L:
if number % 2 is 0:
yield number
evens = allEvens( yourList )
このジェネレーター内包式で同じ結果を得ることができます。
evens = ( number for number in your_list if number % 2 == 0 )
どちらの場合も、電話をかけるnext(evens)
と、で次の偶数が返されyour_list
ます。