lambda的绑定

时间:2017-07-03 06:09:36

标签: python

def f(x):
    return x <5
[x for x in filter(lambda x: f(x), ls)]  #[0,1,2,3,4]
def g(x):
    return lambda: x<5
[x for x in filter(lambda x: g(x), ls)]  # [0,1,2,3,4,5,6,7,8,9]
def h(x):
    return lambda x=x: x<5
[x for x in filter(lambda x: h(x), ls)]  # [0,1,2,3,4,5,6,7,8,9]

有谁可以解释为什么g和h不等同于f? 我认为它们应该是等价的,因为x in和g中的x应该绑定到它们所定义的环境中的x(参见question on closures

2 个答案:

答案 0 :(得分:0)

此处gh返回函数对象,但filter等待返回布尔值或object wich will convert as boolean的函数。对于f,它对您的预期输出是正确的,但对于gh,条件始终为true,因为bool(function object)始终为truehere,python函数是一个可调用的对象。

采取:

def f(x):
    return x < 5

def g(x):
    return lambda: x < 5

def h(x):
    return lambda x=x: x < 5

我建议:

ls = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
print([x for x in ls if f(x)]) # list comprehension
# is equivalent to filter(lambda x: x < 5, ls) iterator
# To get list :
# [x for x in filter(lambda x: x < 5, ls)]
# is equivalent to list(filter(lambda x: x < 5, ls))

输出:

[0,1,2,3,4]

致电g来执行:

g(1)() # True

执行:

 print([x for x in ls if g(x)()])

输出:

[0,1,2,3,4]

致电h来执行:

h(1)() # True

h(1)(5) # False the second argument overrides the first one

执行:

print([x for x in ls if h(x)(x)])
# or print([x for x in ls if h(x)()])

输出:

[0,1,2,3,4]

请参阅documentation以使用过滤器

  

从iterable的那些元素构造一个列表,该函数返回true。 iterable可以是序列,支持迭代的容器,也可以是迭代器。如果iterable是字符串或元组,则结果也具有该类型;否则它总是一个列表。如果function为None,则假定为identity函数,即删除所有可迭代的false元素。

     

请注意,如果函数不是filter(function, iterable),则[item for item in iterable if function(item)]等同于None,如果函数是[item for item in iterable if item],则None等同于lambda arguments: expression

请参阅documentation以使用 lambda表达式

def <lambda>(arguments): return expression

import csv
from django.http import HttpResponse

def some_view(request):
    # Create the HttpResponse object with the appropriate CSV header.
    response = HttpResponse(content_type='text/csv')
    response['Content-Disposition'] = 'attachment; filename="somefilename.csv"'

    writer = csv.writer(response)
    writer.writerow(['First row', 'Foo', 'Bar', 'Baz'])
    writer.writerow(['Second row', 'A', 'B', 'C', '"Testing"', "Here's a quote"])

    return response

答案 1 :(得分:0)

g(x)h(x)正在返回lambda函数本身(<function __main__.<lambda>>),但不会执行它。

尝试举例:g(3)()将返回所需的值。

因此,运行g(x)()h(x)()将起作用:

[x for x in filter(lambda x: g(x)(), ls)]  # [0,1,2,3,4]
[x for x in filter(lambda x: h(x)(), ls)]  # [0,1,2,3,4]

仅运行g(x)h(x)时,每个值都会返回lambda函数,这相当于True函数中的filter语句,并且因此没有过滤任何价值。

当然,在这种情况下你可以运行:

filter(lambda x: x<5, ls)

甚至是better list comprehension approach

[x for x in ls if x<5]