在对象列表Python 3中对所有对象调用方法的惯用方式 [英] Idiomatic way to call method on all objects in a list of objects Python 3
问题描述
我有一个对象列表,它们有一个称为process的方法.在Python 2中,可以做到这一点
I have a list of objects and they have a method called process. In Python 2 one could do this
map(lambda x: x.process, my_object_list)
在Python 3中,这将不起作用,因为map直到遍历了iterable时才调用该函数.一个可以做到这一点:
In Python 3 this will not work because map doesn't call the function until the iterable is traversed. One could do this:
list(map(lambda x: x.process(), my_object_list))
但是随后,您浪费了内存,浪费了一个废弃的列表(如果列表很大,就会出现问题).我也可以使用两行显式循环.但是这种模式对我来说是如此普遍,以至于我不想或者认为我应该每次都编写一个循环.
But then you waste memory with a throwaway list (an issue if the list is big). I could also use a 2-line explicit loop. But this pattern is so common for me that I don't want to, or think I should need to, write a loop every time.
在Python 3中是否有更惯用的方式做到这一点?
Is there a more idiomatic way to do this in Python 3?
推荐答案
不要使用 map
或简单的 for
循环可以做到的列表理解:
Don't use map
or a list comprehension where simple for
loop will do:
for x in list_of_objs:
x.process()
它的长度并不比您用来抽象它的任何函数的时间长,但它明显更清晰.
It's not significantly longer than any function you might use to abstract it, but it is significantly clearer.
当然,如果 process
返回一个有用的值,则一定要使用列表推导.
Of course, if process
returns a useful value, then by all means, use a list comprehension.
results = [x.process() for x in list_of_objs]
或地图
:
results = list(map(lambda x: x.process(), list_of_objs))
有一个可用的函数可使 map
变得不那么笨拙,尤其是如果您要重用调用者的话:
There is a function available that makes map
a little less clunky, especially if you would reuse the caller:
from operator import methodcaller
processor = methodcaller('process')
results = list(map(processor, list_of_objs))
more_results = list(map(processor, another_list_of_objs))
如果要为包装循环的函数寻找一个好名字,Haskell有一个很好的约定:以下划线结尾的函数名将放弃其返回值".(实际上,它放弃了单调操作的结果,但是出于这个答案的目的,我宁愿忽略这种区别.)
If you are looking for a good name for a function to wrap the loop, Haskell has a nice convention: a function name ending with an underscore discards its "return value". (Actually, it discards the result of a monadic action, but I'd rather ignore that distinction for the purposes of this answer.)
def map_(f, *args):
for f_args in zip(*args):
f(*f_args)
# Compare:
map(f, [1,2,3]) # -- return value of [f(1), f(2), f(3)] is ignored
map_(f, [1,2,3]) # list of return values is never built
这篇关于在对象列表Python 3中对所有对象调用方法的惯用方式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!