Idiomatic way to call method on all objects in a list of objects Python 3

吃可爱长大的小学妹 提交于 2021-02-07 19:37:11

问题


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)

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.

Is there a more idiomatic way to do this in Python 3?


回答1:


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.

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]

or map:

results = list(map(lambda x: x.process(), list_of_objs))

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))

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



回答2:


Since you're looking for a Pythonic solution, why would even bother trying to adapt map(lambda x: x.process, my_object_list) for Python 3 ?

Isn't a simple for loop enough ?

for x in my_object_list:
    x.process()

I mean, this is concise, readable and avoid creating an unnecessary list if you don't need return values.



来源:https://stackoverflow.com/questions/51519696/idiomatic-way-to-call-method-on-all-objects-in-a-list-of-objects-python-3

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!