2017-07-03 58 views
1
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在g和h應綁定到的,因爲它們在所定義的環境的X(見本question on closureslambdas的綁定

+4

'F'返回一個布爾值。 'g'和'h'返回功能。他們爲什麼會相當? – user2357112

+0

條件語句中的函數始終視爲true。 – yoku2010

回答

0

這裏gh返回功能對象,但是filter等待它返回一個功能一個布爾值或object wich will convert as boolean。使用f對於您的預期輸出是正確的,但對於gh,條件始終爲true,因爲bool(function object)總是true請參閱here,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使用濾波器

從迭代的那些元件爲哪些函數返回true構造一個列表。可迭代可以是序列,支持迭代的容器或迭代器。如果iterable是一個字符串或一個元組,結果也具有該類型;否則它總是一個列表。如果函數爲None,那麼假定標識函數,即刪除所有可迭代的元素爲false。

請注意,filter(function, iterable)相當於[item for item in iterable if function(item)]如果功能不是None[item for item in iterable if item]如果功能是None

參見documentation使用lambda表達式

lambda arguments: expression用:

def <lambda>(arguments): 
    return expression 
+1

我更新了帖子以澄清這點thx;) – glegoux

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)將返回每每個值,這相當於True聲明filter功能lambda功能本身,因此沒有價值過濾。


當然,在這種情況下,你可以運行:

filter(lambda x: x<5, ls) 

甚至better list comprehension approach

[x for x in ls if x<5]