python :(ラムダ)関数のdict

ヘンシング

ラムダ関数をディクショナリに格納するときに、奇妙な動作が発生しました。ループ内の関数にデフォルト値を渡そうとすると、最後のデフォルト値のみが使用されます。

ここにいくつかの最小限の例があります:

#!/usr/bin/env python
# coding: utf-8

def myfct(one_value, another_value):
    "do something with two int values"
    return one_value + another_value

fct_dict = {'add_{}'.format(number): (lambda x: myfct(x, number))
            for number in range(10)}

print('add_3(1): {}, id={}'.format(fct_dict['add_3'](1), id(fct_dict['add_3'])))
print('add_5(1): {}, id={}'.format(fct_dict['add_5'](1), id(fct_dict['add_5'])))
print('add_9(1): {}, id={}'.format(fct_dict['add_9'](1), id(fct_dict['add_9'])))

出力は次のようになります

add_3(1): 10, id=140421083875280
add_5(1): 10, id=140421083875520
add_9(1): 10, id=140421083876000

異なる関数(idは同一ではありません)を取得しますが、すべての関数は同じ2番目の引数を使用します。

誰かが何が起こっているのか説明できますか?

同じことがpython2、python3、pypyにも当てはまります...

ダーク

修正:

def make_closure(number):
    return lambda x: myfct(x, number)

使用されます

{'add_{}'.format(number): make_closure(number) for number in range(10)}

この動作の理由は、変数number(ここでは名前付きメモリの場所)がループのすべての反復で同じであるためです(ただし、実際の値は反復ごとに変化します)。ここでの「ループ」とは、内部的にループに基づいている辞書理解を指します。lambdaループで作成されたすべてのインスタンスは、同じ「場所」で閉じられ、最後に割り当てられた値が保持されます(ループの最後の反復で)。

次のコードは、実際にその下で発生するものではありませんこれは、概念に光を当てるために提供されているだけです。

# Think of a closure variable (like number) as being an instance
# of the following class

class Cell:
    def __init__(self, init=None):
        self.value = None

# Pretend, the compiler "desugars" the dictionary comprehension into
# something like this:

hidden_result_dict = {}
hidden_cell_number = Cell()

for number in range(10):
    hidden_cell_number.value = number
    hidden_result_dictionary['add_{}'.format(number)] = create_lambda_closure(hidden_cell_number)

操作lambdaによって作成されたすべてのクロージャcreate_lambda_closureはまったく同じCellインスタンスを共有し、value実行時(つまり、クロージャが実際に呼び出されたとき)に属性を取得します。その時までに、valueこれまでに割り当てられた最後の値を参照します。

の値はhidden_result_dict、dictの理解の結果として答えられます。(繰り返しますが、これは「概念」レベルで読み取ることのみを目的としています。PythonVMによって実行される実際のコードとは関係ありません)。

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

分類Dev

ラムダ関数のdictを使用したPythonでの奇妙な動作

分類Dev

Python:ラムダ関数

分類Dev

ラムダ関数のpythonとpython-joseのエラー

分類Dev

Pythonラムダ関数の動的作成(パンダの例)

分類Dev

Python、groupbyの引数としてのラムダ関数

分類Dev

クラス内のPythonラムダ関数とdefの違い

分類Dev

Pythonの再帰的多変数ラムダ関数

分類Dev

Pythonのラムダ関数の参照の問題

分類Dev

Pythonラムダ関数でのOR演算子の使用

分類Dev

Pythonでのラムダのソート関数を理解する

分類Dev

別のラムダ関数からラムダ関数のメソッドを呼び出す-Python

分類Dev

Pythonのラムダ関数に値を割り当てる方法は?

分類Dev

ラムダ関数内のPython反復プロセス

分類Dev

Pythonでラムダ内の関数を操作する方法は?

分類Dev

出力なしのPythonラムダ呼び出し関数

分類Dev

numpysnp.fromfunctionを使用したPythonラムダ関数の評価

分類Dev

ラムダ関数とPythonでのフィルタリング

分類Dev

Python関数の__dict__

分類Dev

Pythonの関数の引数にラムダを適用できますか?

分類Dev

Pythonパンダ-他の列にアクセスするラムダ関数

分類Dev

自分の関数でランダムなライブラリ関数を使用するpython3

分類Dev

関数をパラメーター化するPythonの方法(ラムダなし)

分類Dev

ラムダと通常の関数のPythonの違いは何ですか?

分類Dev

ラムダと通常の関数のPythonの違いは何ですか?

分類Dev

Pythonのラムダ関数の戻り値の型は何ですか?

分類Dev

円の中にランダムなペアを生成するPythonのランダム関数

分類Dev

不思議なPythonパンダラムダ関数エラー

分類Dev

Python、なぜこのラムダ関数が正しくないのですか?

分類Dev

Pythonのラムダ関数のクロージャが無効です

Related 関連記事

  1. 1

    ラムダ関数のdictを使用したPythonでの奇妙な動作

  2. 2

    Python:ラムダ関数

  3. 3

    ラムダ関数のpythonとpython-joseのエラー

  4. 4

    Pythonラムダ関数の動的作成(パンダの例)

  5. 5

    Python、groupbyの引数としてのラムダ関数

  6. 6

    クラス内のPythonラムダ関数とdefの違い

  7. 7

    Pythonの再帰的多変数ラムダ関数

  8. 8

    Pythonのラムダ関数の参照の問題

  9. 9

    Pythonラムダ関数でのOR演算子の使用

  10. 10

    Pythonでのラムダのソート関数を理解する

  11. 11

    別のラムダ関数からラムダ関数のメソッドを呼び出す-Python

  12. 12

    Pythonのラムダ関数に値を割り当てる方法は?

  13. 13

    ラムダ関数内のPython反復プロセス

  14. 14

    Pythonでラムダ内の関数を操作する方法は?

  15. 15

    出力なしのPythonラムダ呼び出し関数

  16. 16

    numpysnp.fromfunctionを使用したPythonラムダ関数の評価

  17. 17

    ラムダ関数とPythonでのフィルタリング

  18. 18

    Python関数の__dict__

  19. 19

    Pythonの関数の引数にラムダを適用できますか?

  20. 20

    Pythonパンダ-他の列にアクセスするラムダ関数

  21. 21

    自分の関数でランダムなライブラリ関数を使用するpython3

  22. 22

    関数をパラメーター化するPythonの方法(ラムダなし)

  23. 23

    ラムダと通常の関数のPythonの違いは何ですか?

  24. 24

    ラムダと通常の関数のPythonの違いは何ですか?

  25. 25

    Pythonのラムダ関数の戻り値の型は何ですか?

  26. 26

    円の中にランダムなペアを生成するPythonのランダム関数

  27. 27

    不思議なPythonパンダラムダ関数エラー

  28. 28

    Python、なぜこのラムダ関数が正しくないのですか?

  29. 29

    Pythonのラムダ関数のクロージャが無効です

ホットタグ

アーカイブ