質問

以下の試験に失敗した:

#!/usr/bin/env python
def f(*args):
    """
    >>> t = 1, -1
    >>> f(*map(lambda i: lambda: i, t))
    [1, -1]
    >>> f(*(lambda: i for i in t)) # -> [-1, -1]
    [1, -1]
    >>> f(*[lambda: i for i in t]) # -> [-1, -1]
    [1, -1]
    """
    alist = [a() for a in args]
    print(alist)

if __name__ == '__main__':
    import doctest; doctest.testmod()

言い換えれば

>>> t = 1, -1
>>> args = []
>>> for i in t:
...   args.append(lambda: i)
...
>>> map(lambda a: a(), args)
[-1, -1]
>>> args = []
>>> for i in t:
...   args.append((lambda i: lambda: i)(i))
...
>>> map(lambda a: a(), args)
[1, -1]
>>> args = []
>>> for i in t:
...   args.append(lambda i=i: i)
...
>>> map(lambda a: a(), args)
[1, -1]
役に立ちましたか?

解決

て異なるので、価値の i 両、発電機の発現のリストのcompを評価しの遅延、すなわち場合の匿名の機能の呼び出し f.
その時に、 i は、最後の値の場合 t, は-1になります。

なので基本的には、このリストの読解力は(またはgenexp):

x = []
i = 1 # 1. from t
x.append(lambda: i)
i = -1 # 2. from t
x.append(lambda: i)

現在のlambdas活の閉鎖を参照 i, ものの、 i は、-1の両方の場合、この値で割り当てます。

したい場合にはラムダの現在値 i, い

f(*[lambda u=i: u for i in t])

このように、力の評価 i 当時の閉鎖を作成します。

編集:あ差発電機の表現およびリストの理解:後者に漏れのループ変数の周囲です。

他のヒント

ラムダは値ではなく変数をキャプチャするため、コード

lambda : i

クロージャーでバインドされている現在の値を常に返します。呼び出されるまでに、この値は-1に設定されています。

必要なものを取得するには、ラムダの作成時に実際のバインディングをキャプチャする必要があります。

>>> f(*(lambda i=i: i for i in t)) # -> [-1, -1]
[1, -1]
>>> f(*[lambda i=i: i for i in t]) # -> [-1, -1]
[1, -1]

f = lambda:i は次と同等です:

def f():
    return i

g = lambda i = i:i は次と同等です:

def g(i=i):
    return i

i は、最初の無料変数です。 2番目のケースでは関数パラメーターにバインドされています。つまり、その場合はローカル変数です。デフォルトパラメータの値は、関数の定義時に評価されます。

Generator式は、 lambda 式の i 名の最も近い囲みスコープ( i が定義されている)です。したがって、 i はそのブロックで解決されます:

f(*(lambda: i for i in (1, -1)) # -> [-1, -1]

i lambda i:... ブロックのローカル変数であるため、参照するオブジェクトはそのブロックで定義されています:

f(*map(lambda i: lambda: i, (1,-1))) # -> [1, -1]
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top