2014-09-02 40 views
0

此代碼對我看起來像在Python有可能是這樣做的更好的方式:使返回值的簡單修正更地道的方式

val = some_heavy_foo(slow=True, side_effects=True, bar=lot_of_data) 
if val is None: 
    val = 0 

是嗎?

一個可能的使用案例:

total = 0 
for lot_of_data in lots_of_data_list: 
    val = some_heavy_foo(slow=True, side_effects=True, bar=lot_of_data) 
    if val is None: 
     val = 0 
    total += val 

我想在這裏使用sum(),但當然:

TypeError: unsupported operand type(s) for +: 'int' and 'NoneType' 

回答

3

爲了您的具體使用情況:

from functools import partial 
from operator import is_not 
from itertools import ifilter 

# Create a callable that only needs bar 
f = partial(some_heavy_foo, slow=True, side_effects=True) 

# Ignore None values 
is_not_none = partial(is_not, None) 

# Some return values of f that aren't None 
total = sum(ifilter(is_not_none, f(bar=x) for x in lot_of_data)) 
+1

括號的數量使得危險的樣子LISP雖然。 – chiffa 2014-09-02 21:27:10

+0

哦,我喜歡!雖然,第一個部分'f'並不是真的必要,除了將總和保持在一行。 – frnhr 2014-09-02 21:29:07

1

這取決於你真正想要的。我已經看到了從JavaScript的人羣的人往往喜歡or

val = some_heavy_foo(slow=True, side_effects=True, bar=lot_of_data) or 0 

,因爲這是一個很常見的JavaScript成語。當然,這會將所有的虛假值翻譯爲0。在這種情況下,這可能是很好的,因爲通常你不應該寫代碼,你不知道你是否有整數或列表或其他東西...

就個人而言,我更贊成說你的意思是什麼(即按照你最初的方式來寫),但這只是我的偏好。

你也可以推遲檢查,直到下一行:

val = some_heavy_foo(slow=True, side_effects=True, bar=lot_of_data) 
total += 0 if val is None else val 

,但是,我不相信這是好多了......

0

這是簡潔的,但如果你不習慣了功能性風格,我不確定它好多了。正如在另一個答案中,這給了你任何「falsy」值爲0,並總結一切。

tot = sum(map(lambda x: x if x else 0, 
    [some_heavy_foo(slow=True, side_effects=True, bar=data) for data in lots_of_data]))