yield from" 文を Python 2.7 のコードに変換する
質問
私はPython 3.2で以下のコードを持っていた、私はPython 2.7でそれを実行したいと思った。私はそれを変換しました。
missing_elements
のコードを両方のバージョンに入れました)しかし、私はそれを行うための最も効率的な方法であるかどうかわからない。基本的に、もし2つの
yield from
の中で上半分と下半分で以下のような呼び出しがあった場合はどうなるでしょうか?
missing_element
関数で呼び出すのですか?上半分と下半分のエントリーは、1つのリストで互いに追加され、親再帰関数が
yield from
を持つ親再帰関数が両方の半分を一緒に呼び出して使用できるようにするためですか?
def missing_elements(L, start, end): # Python 3.2
if end - start <= 1:
if L[end] - L[start] > 1:
yield from range(L[start] + 1, L[end])
return
index = start + (end - start) // 2
# is the lower half consecutive?
consecutive_low = L[index] == L[start] + (index - start)
if not consecutive_low:
yield from missing_elements(L, start, index)
# is the upper part consecutive?
consecutive_high = L[index] == L[end] - (end - index)
if not consecutive_high:
yield from missing_elements(L, index, end)
def main():
L = [10, 11, 13, 14, 15, 16, 17, 18, 20]
print(list(missing_elements(L, 0, len(L)-1)))
L = range(10, 21)
print(list(missing_elements(L, 0, len(L)-1)))
def missing_elements(L, start, end): # Python 2.7
return_list = []
if end - start <= 1:
if L[end] - L[start] > 1:
return range(L[start] + 1, L[end])
index = start + (end - start) // 2
# is the lower half consecutive?
consecutive_low = L[index] == L[start] + (index - start)
if not consecutive_low:
return_list.append(missing_elements(L, start, index))
# is the upper part consecutive?
consecutive_high = L[index] == L[end] - (end - index)
if not consecutive_high:
return_list.append(missing_elements(L, index, end))
return return_list
どのように解決するのですか?
歩留まりの結果を利用しない場合*は、次のようにします。 常に これを回す。
yield from foo
... をこのようにします。
for bar in foo:
yield bar
パフォーマンスコスト**はあるかもしれませんが、セマンティックな違いは決してありません。
2 つのハーフ (上側と下側) のエントリは 1 つのリストで互いに追加され、yield from を持つ親再帰関数が両方のハーフを一緒に呼び出して使用できるようになりますか。
いいえ!イテレータとジェネレータの全体的なポイントは、実際のリストを構築してそれらを一緒に追加しないことです。
しかし の効果 も同様で、1つから降伏し、次に別のものから降伏するだけです。
上半分と下半分を "lazy list" と考えると、そう、これはより大きな "lazy list" を作成する "lazy append" として考えることができます。そして、もしあなたが
list
を呼び出すと、もちろん、親関数の結果に対して
は
を得ることができます。
list
を実行した場合に得られるはずだった二つのリストを足し合わせたものと同じです。
yield list(…)
ではなく
yield from …
.
でも、逆に考えた方がわかりやすいと思います。これは、まさに
for
ループが行うことと全く同じです。
2つのイテレータを変数に保存し、ループさせた場合
itertools.chain(upper, lower)
をループさせたとしたら、それは1つ目をループさせてから2つ目をループさせたのと同じですよね?ここでは違いはありません。実際には
chain
をそのまま実装することができます。
for arg in *args:
yield from arg
* ジェネレータが呼び出し元に渡す値ではなく、ジェネレータ内のyield式の値そのものです(呼び出し元は
send
メソッドを使って呼び出し元から来るものです)、で説明されているように
PEP 342
. あなたの例ではこれらを使っていませんね。そして、実際のコードでも使っていないことに賭けてもいいくらいです。しかし、コルーチン形式のコードではしばしば
yield from
式の値を使うことがあります。
PEP 3156
を参照してください。このようなコードは通常 Python 3.3 ジェネレータの他の機能、特に、新しい
StopIteration.value
から、同じ
PEP 380
を導入した
yield from
-を導入した PEP 380 で、書き直さなければならないでしょう。しかし、そうでない場合は、PEPを使えば、完全に恐ろしいほど面倒な同等のものを表示してくれますし、もちろん、気にしない部分を切り詰めることができます。そして、もし式の値を使わなければ、上の2行に縮小されます。
** 巨大なものではありませんし、Python 3.3を使うか、コードを完全に再構築しない限り、どうすることもできません。リスト内包を Python 1.5 のループに変換するのとまったく同じケース、または、バージョン X.Y で新しい最適化があり、古いバージョンを使用する必要がある他のケースと同じです。
関連
-
[解決済み] Pythonの辞書からキーを削除するにはどうしたらいいですか?
-
[解決済み] なぜC++はPythonよりもstdinからの行の読み込みが遅いのですか?
-
[解決済み] Pythonのswitch文の代用品?
-
[解決済み] Pythonでファイル名から拡張子を抽出する
-
[解決済み] Pythonで整数から文字列に変換する
-
[解決済み] Pythonでパスから拡張子なしでファイル名を取得する方法は?
-
[解決済み] Pythonで文字列からbooleanに変換する?
-
[解決済み] Python 3.3のyield from構文は、実際にはどのような用途に使われるのでしょうか。
-
[解決済み] ある部分文字列のすべての出現箇所を見つけるにはどうすればよいですか?
-
[解決済み] Pythonでランダムなファイル名を生成する最良の方法
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] 2つの線分が交差しているかどうかを確認するにはどうすればよいですか?
-
[解決済み] Pythonのキャッシュライブラリはありますか?
-
[解決済み] pandasのDataFrameから空のセルを含む行を削除する
-
[解決済み] なぜ(0-6)は-6=偽なのか?重複
-
[解決済み] ファブリック経由でデプロイユーザとしてvirtualenvを有効化する
-
[解決済み] 古いバージョンのPythonにおける辞書のキーの並び順
-
[解決済み] Ctrl-CでPythonスクリプトを終了できない
-
[解決済み] Python Empty Generator 関数
-
[解決済み] if 節の終了方法
-
[解決済み] ジェネレータは再帰的か?