在对象列表Python 3中对所有对象调用方法的惯用方式

时间:2018-07-25 13:08:39

标签: python python-3.x list methods

我有一个对象列表,它们有一个称为process的方法。在Python 2中,可以做到这一点

string(/testng-results/suite/test/class/test-method[@name='test']/@status)

在Python 3中,这将不起作用,因为map直到遍历了iterable时才调用该函数。一个可以做到这一点:

map(lambda x: x.process, my_object_list)

但是随后,您浪费了内存,浪费了一个废弃的列表(如果列表很大,就会出现问题)。我也可以使用两行显式循环。但是这种模式对我来说是如此普遍,以至于我不想或者认为我应该每次都编写一个循环。

在Python 3中是否有更惯用的方式做到这一点?

2 个答案:

答案 0 :(得分:4)

既然您正在寻找Pythonic解决方案,为什么还要费心尝试为Python 3改编map(lambda x: x.process, my_object_list)呢?

一个简单的for循环还不够吗?

for x in my_object_list:
    x.process()

我的意思是,这简洁可读,并且如果不需要返回值,请避免创建不必要的列表

答案 1 :(得分:3)

不要使用map或简单的for循环就能完成的列表理解:

for x in list_of_objs:
    x.process()

它并没有比您用来抽象它的任何函数长很多,但是它明显更清晰了。

当然,如果process返回有用的值,则一定要使用列表推导。

results = [x.process() for x in list_of_objs]

map

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

有一个可用的函数可以使map不再那么笨拙,特别是如果您要重用调用者的话:

from operator import methodcaller
processor = methodcaller('process')
results = list(map(processor, list_of_objs))
more_results = list(map(processor, another_list_of_objs))

如果要为包装循环的函数寻找一个好名字,Haskell有一个很好的约定:以下划线结尾的函数名将放弃其“返回值”。 (实际上,它丢弃了单声道操作的结果,但出于此答案的目的,我宁愿忽略该区别。)

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