使用map()vs有没有价值? [英] Is there a value in using map() vs for?
问题描述
<$>
<$>
item.my_func()
如果有道理,我想使它成为map()。那可能吗?什么是类似的例子?
您可以使用 map
而不是 for
循环,但是由于您没有使用 item.my_func()
的结果,所以不推荐。如果你想将一个没有副作用的函数应用到列表的所有元素,应该使用 map
。在所有其他情况下,使用一个明确的for循环。
另外,从Python 3.0开始 map
返回一个生成器,所以在这种情况下, map
的行为不会相同(除非您明确地评估生成器返回的所有元素,例如调用 list
就可以了)
编辑: kibibu 在评论中要求澄清为什么 map
的第一个参数不应该是带副作用的函数。我会回答这个问题的一个镜头:
$ b $ p $ map $ 是为了传递一个函数
f
在数学意义上 。在这种情况下,将第二个参数的元素(只要它们返回到原始元素中)的顺序应用到 f
订单,当然)。更重要的是,在这些情况下, map(g,map(f,l))
在语义上相当于 map(lambda x:g(f )),l)
,无论 f
和 g
应用到它们各自的输入。
例如, map
是否返回并不重要和迭代器或一个完整的列表。然而,如果 f
和/或 g
会导致副作用,那么只有在 map(g,map(f,l))
是在任何阶段将 g
应用于第一个在 map(f,l)之前由
元素 apply map(f,l)
返回的 f
添加到 l
的(n + 1) st元素。 (这意味着 map
必须执行最迟的迭代 - 它在Python 3中执行,而不是在Python 2中执行)
更进一步:即使我们假设 map(f,l)
是例如通过 itertools.tee $ c $在提供给外部的
。上面的讨论可能看起来是理论性的,但是随着程序变得越来越复杂,它们变得更难以推理,因此更难以调试。确保有些东西是不变的,缓解这个问题,并且实际上可以防止一类错误。 map
调用之前,c>
map
以多种(纯粹)功能语言提醒许多人其功能对应。传递一个副作用的功能会混淆这些人。因此,作为替代方法(即使用显式循环)比调用 map
更加困难,强烈建议限制使用 map
到那些要应用的函数不会导致副作用的情况。 Does map() iterate through the list like "for" would? Is there a value in using map vs for?
If so, right now my code looks like this:
for item in items:
item.my_func()
If it makes sense, I would like to make it map(). Is that possible? What is an example like?
You could use map
instead of the for
loop you've shown, but since you do not appear to use the result of item.my_func()
, this is not recommended. map
should be used if you want to apply a function without side-effects to all elements of a list. In all other situations, use an explicit for-loop.
Also, as of Python 3.0 map
returns a generator, so in that case map
will not behave the same (unless you explicitly evaluate all elements returned by the generator, e.g. by calling list
on it).
Edit: kibibu asks in the comments for a clarification on why map
's first argument should not be a function with side effects. I'll give answering that question a shot:
map
is meant to be passed a function f
in the mathematical sense. Under such circumstances it does not matter in which order f
is applied to the elements of the second argument (as long as they are returned in their original order, of course). More importantly, under those circumstances map(g, map(f, l))
is semantically equivalent to map(lambda x: g(f(x)), l)
, regardless of the order in which f
and g
are applied to their respective inputs.
E.g., it doesn't matter whether map
returns and iterator or a full list at once. However, if f
and/or g
cause side effects, then this equivalence is only guaranteed if the semantics of map(g, map(f, l))
are such that at any stage g
is applied to the first n elements returned by map(f, l)
before map(f, l)
applies f
to the (n + 1)st element of l
. (Meaning that map
must perform the laziest possible iteration---which it does in Python 3, but not in Python 2!)
Going one step further: even if we assume the Python 3 implementation of map
, the semantic equivalence may easily break down if the output of map(f, l)
is e.g. passed through itertools.tee
before being supplied to the outer map
call.
The above discussion may seem of a theoretic nature, but as programs become more complex, they become more difficult to reason about and therefore harder to debug. Ensuring that some things are invariant alleviates that problem somewhat, and may in fact prevent a whole class of bugs.
Lastly, map
reminds many people of its truly functional counterpart in various (purely) functional languages. Passing it a "function" with side effects will confuse those people. Therefore, seeing as the alternative (i.e., using an explicit loop) is not harder to implement than a call to map
, it is highly recommended that one restricts use of map
to those cases in which the function to be applied does not cause side effects.
这篇关于使用map()vs有没有价值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!