2013-01-21 32 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(...)),这使得它更糟糕。