Pythonでは、次のようなyieldキーワードを関数の本体に挿入することで、反復関数を簡単に定義できます。
def gen():
for i in range(100):
yield i
値を生成しない(値0を生成する)ジェネレーター関数を定義するには、pythonが通常の関数ではなくジェネレーターであることを認識できないため、次のコードは機能しません。
def empty():
pass
私は次のようなことができます
def empty():
if False:
yield None
しかし、それは非常にいものです。空のイテレータ関数を実現する良い方法はありますか?
ジェネレーターでreturn
を1回使用できます。何も生成せずに反復を停止するため、関数をスコープ外に実行する代わりの明示的な代替手段を提供します。したがって、yield
を使用して関数をジェネレーターにしますが、その前にreturn
を付けて、何かを生成する前にジェネレーターを終了します。
_>>> def f():
... return
... yield
...
>>> list(f())
[]
_
私はそれがあなたが持っているものよりもはるかに優れていると確信していません-それは単にno-op if
ステートメントをno-op yield
ステートメントに置き換えます。しかし、それはより慣用的です。 yield
を使用するだけでは機能しないことに注意してください。
_>>> def f():
... yield
...
>>> list(f())
[None]
_
iter(())
を使用しないのですか?この質問では、空のジェネレーター関数について具体的に尋ねます。そのため、一般的に空のイテレータを作成する最良の方法についての質問ではなく、Pythonの構文の内部整合性についての質問と考えています。
質問が実際に空のイテレータを作成する最良の方法についてである場合、代わりにiter(())
を使用することについて Zectbumo に同意するかもしれません。ただし、iter(())
は関数を返さないことに注意してください。空のイテラブルを直接返します。 returnsiterableであるcallableを期待するAPIで作業しているとします。次のようなことをする必要があります。
_def empty():
return iter(())
_
(クレジットは、この回答の最初の正しいバージョンを提供するために nutb に移動する必要があります。)
今、あなたは上記をより明確にするかもしれませんが、私はそれがあまり明確でない状況を想像することができます。 (作成された)ジェネレーター関数定義の長いリストのこの例を考えてみましょう:
_def zeros():
while True:
yield 0
def ones():
while True:
yield 1
...
_
その長いリストの最後に、次のようなyield
が含まれる何かを見たいです。
_def empty():
return
yield
_
または、Python 3.3以降( [〜#〜] dsm [〜#〜] で示唆されているように)、これ:
_def empty():
yield from ()
_
yield
キーワードの存在は、これが他のすべてのジェネレーター関数とまったく同じように、単なるジェネレータ関数であることを一目で明らかにします。 iter(())
バージョンが同じことを実行していることを確認するには、もう少し時間がかかります。
微妙な違いですが、正直に言って、yield
ベースの関数はより読みやすく保守しやすいと思います。
iter(())
必須ジェネレーターではありません。おいおい!
Python 3.3(私は_yield from
_キックをしているので、@ senderleは私の最初の考えを盗んだからです):
_>>> def f():
... yield from ()
...
>>> list(f())
[]
_
ただし、iter([])
または_(x)range(0)
_が同様にうまく機能しないこのユースケースを考え出すのに苦労しています。
別のオプションは次のとおりです。
(_ for _ in ())
私は次を好む:
def foo():
raise StopIteration()
yield
「yield」はジェネレータに変換し、ExceptionはNoneが結果に含まれないことを意味します(純粋に空の結果)。
ジェネレーター関数でなければなりませんか?そうでない場合はどうですか
def f():
return iter([])
空のイテレータを作成する「標準的な」方法は、iter([])のようです。 []をiter()のデフォルト引数にすることを提案しました。これは適切な引数で拒否されました。 http://bugs.python.org/issue25215 を参照してください-Jurjen
実際に関数を必要とし、実際にジェネレータを必要とするあなたのために
empty = lambda: (_ for _ in ())
generator = (item for item in [])