2013-01-21 31 views
0

告訴某人「我想爲iterable中的每個元素應用func的副作用」的首選方式是什麼。python map中的副作用(python「do」block)

# Option 1... clear, but two lines. 
for element in iterable: 
    func(element) 

# Option 2... even more lines, but could be clearer. 
def walk_for_side_effects(iterable): 
    for element in iterable: 
     pass 

walk_for_side_effects(map(func, iterable)) # Assuming Python3's map. 

# Option 3... builds up a list, but this how I see everyone doing it. 
[func(element) for element in iterable] 

我喜歡選擇2;標準庫中是否有一個功能已經相當於?

+5

你應該使用選項1.它是最好的溝通你的代碼是必要的,並不會構造無用的結果列表。 – millimoose

+0

'地圖'和列表的理解是等價的。 'walk_for_side_effects'電話沒用。使用選項1. –

+1

@PavelAnossov:不在python 3中; 'map()'返回一個迭代器。 –

回答

6

避免誘惑變得聰明。使用選項1,它的意圖是清楚明確的;您正在將函數func()應用於迭代器中的每個元素。

選項2只是混淆了每個人,尋找walk_for_side_effects應該做什麼(它肯定讓我困惑,直到我意識到你需要在Python 3中迭代map())。

當你從func(),從來沒有實際得到結果的副作用時,應使用選項3。毆打任何人只是爲了副作用。應該使用列表解析來生成列表,而不是執行其他操作。相反,讓你更難理解和維護你的代碼(並且建立一個所有返回值的列表啓動較慢)。

+1

)有一天我會理解爲什麼人們認爲寫「爲了我在seq:do_something(i)」中是粗糙的,但是顛倒了順序,刪除了冒號,並添加了方括號裏面是精緻的高度,讓我想起辛普森一家快速思考的汽車推銷員,當時他所展示的汽車突然被子彈擊中:「這些是速度孔,它們讓汽車走得更快。」 – DSM

+0

這是因爲它需要一個縮進塊和引入一個不必要的變量,對於習慣於函數式編程的人來說,這感覺非常骯髒。 – ToBeReplaced

+0

@ToBeReplaced:具有副作用的函數不是真正的函數式編程,是嗎? –

2

這已被多次詢問,例如,herehere。但這是一個有趣的問題。列表解析是爲了用於別的東西。

其他選項包括

  1. 使用map() - 基本相同的樣品
  2. 使用filter() - 如果你的函數返回None,你會得到一個空列表
  3. 只是一個普通的for -loop

而純循環是最好的方法。在這種情況下,在語義上是正確的,所有其他方式,包括列表理解,濫用概念的副作用。

在Python 3.x中,map()filter()是生成器,因此在您遍歷它們之前不會執行任何操作。所以我們需要,例如,list(map(...)),這使得它更糟糕。