予期しない動作: 変数スコープを変更するリスト内包表記
Python のリスト内包表記はデータ操作のための強力なツールですが、隠れた癖があります。予期せぬ事態を招く可能性がある
問題
Python 2 (およびそれ以前) では、リスト内包表記によってループ制御変数がループの最後の値に「再バインド」される可能性があります。理解の範囲は終わりました。これにより、驚くべき動作が発生する可能性があります。
x = "original value" squares = [x**2 for x in range(5)] print(x) # Prints 4 in Python 2!
この例では、ループ制御変数 x がリスト内包表記内のループ (4) の最後の値に再割り当てされます。これは、print(x) が内包表記の外で呼び出された場合、「元の値」の代わりに 4 を出力することを意味します。
説明
上記の動作は結果ですリスト内包表記が Python 2 で最初に実装された方法です。リスト内包表記を可能な限り効率的にするために、ループ制御変数が周囲の変数にリークされました。 scope.
Python 3 の修正
Python 3 では、この動作が変更されました。リスト内包表記は、内包表記の外でループ制御変数を再バインドしなくなりました。これは、ループ制御変数を再バインドしない、リスト内包表記とジェネレーター式の間の一貫性を向上させるために行われました。
Guido van Rossum の説明
Guido van Rossum、作成者Python の氏は、Python 3 でのこの変更の背後にある理由を次のように説明しました。
「私たちは、ジェネレーター式と同じ実装戦略を使用して、リスト内包表記の「ちょっとした秘密」を修正します。したがって、Python 3 では、上記の例は「before」を出力し、リスト内包表記の「x」が一時的に証明されます。影を付けますが、周囲の「x」を上書きしません。 scope."
結論
リスト内包表記の動作は最初は直観に反するように思えるかもしれませんが、Python 2 と Python 3 の両方でどのように動作するかを理解することが重要です。この知識は、潜在的なバグを回避し、より堅牢なコードを作成するのに役立ちます。
以上がPython のリスト内包表記によって変数の値が変更されるのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。