リスト内包表記と名前の再バインド
リスト内包表記は、Python でリストを作成するための簡潔な構文です。ただし、これらはスコープとの相互作用で予期しない動作を示します。
次のコードを考えてみましょう:
x = "original value" squares = [x**2 for x in range(5)] print(x) # Prints 4 in Python 2!
この例では、リスト内包表記は変数 x を、次の反復からの現在の値に再バインドします。範囲(5)。この動作は名前の再バインドとして知られています。
名前の再バインドの理由
Python 2 では、リストの内包表記はジェネレーター式とは異なる方法で実装されました。リスト内包表記は、ループ制御変数を周囲のスコープにリークすることで速度を最適化しました。一方、ジェネレーター式は別個の実行フレームを使用して、この漏洩を防止しました。
Python 3 の変更点
Python 3 では、この区別は削除されました。リスト内包表記では、ジェネレーター式と同じ実装が使用されるようになりました。その結果、Python 3 では名前の再バインドは発生しなくなりました。
結果
名前の再バインドは、特に同じ変数名が使用されている場合に、予期しない動作やエラーを引き起こす可能性があります。はリスト内包表記と周囲のスコープの両方で使用されます。質問で述べたように、リスト内包表記の一時変数にアンダースコア接頭辞を使用することでこの問題を軽減できます。
Python の作成者である Guido van Rossum 氏は、この変更の背後にある歴史を説明しました: Python 2 では、リスト内包表記が漏洩しましたパフォーマンスを最適化するための初期実装の成果物としてのループ制御変数。ただし、Python 3 では、これはちょっとした汚い秘密とみなされ、ジェネレーター式と同じ実装戦略を採用することで修正される必要がありました。
以上がPython 2 のリスト内包表記が変数を再バインドするのはなぜですか? Python 3 ではこれがどのように変更されましたか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。