3

所以我有一个包含许多类实例的列表。

随着时间的推移,我想在每一步都调用run类的方法。

到目前为止,我有以下内容。但是有没有更好或更 Pythonic 的方式来实现这个for c in objs:块?

谢谢!

#!/usr/bin/python

class the_class:
    def __init__(self):
        self.num=1
    def run(self):
        self.num+=1

def main():
    objs=[]
    objs.append(the_class())
    objs.append(the_class())
    objs.append(the_class())

    for t in range(10):
        for c in objs:
            c.run()

    print objs[0].num

main()
4

4 回答 4

10

不,你所拥有的是完全合理和 Pythonic 的。

列表理解语法:

[c.run() for c in objs]

为您节省一行,但使用列表推导来处理副作用通常被认为是不好的风格。

于 2012-04-17T20:30:16.470 回答
6

不,你所拥有的一切都很好。

在此处使用列表理解或映射会使您的代码不那么清晰且难以阅读。我强烈建议不要这样做

列表推导式旨在创建一个列表。在你想制作循环的地方,使用循环。

即使您确实需要对此进行优化(并且无论如何使用列表组合或映射都不太可能是有效的优化),但当您有证据证明这是一个瓶颈时就这样做。可读性是第一位的,只优化你必须的地方。

于 2012-04-17T20:50:55.430 回答
1

还有一个map内置函数,它与列表推导基本相同:

map(lambda x:x.run(),objs) 

但大多数人认为列表推导更“pythonic”。此外,人们对使用列表推导来处理副作用的任何保留也可能适用map。我提出它的唯一原因是因为该multiprocessing模块有一个Pool类,它有一个 map 方法可以并行进行计算,并且与内置的基本相同maphttp://docs.python.org/library/multiprocessing.html)。如果 run 方法需要一段时间才能完成,并且每个方法都独立于其他方法,那么它可能是值得的。

编辑

lambda如评论中所述,您可以使用 operator 模块更快地执行此操作(删除)。但是,重点是(并且仍然是)您可以使用mapmultiprocessing.Pool.map几乎可以互换使用,并在许多应用程序中使用后者来提升性能。

于 2012-04-17T20:38:51.533 回答
0

对于 python 3,您不能简单地使用 map,因为您必须将其作为生成器来处理。

def exhaust(gen):
    for _ in gen: pass

# Using map
exhaust(map(lambda x: x.run(), c))

# Using generator comprehension (better)
exhaust(x.run() for x in c)

或者,您可以创建一个虚拟函数,并使用*运算符:

def nop(*args): pass
nop(*(x.run() for x in c))

正如其他人所指出的,这些都不是很好读的。坚持你所拥有的,这样人们就可以阅读它。

编辑:改进排气功能,谢谢wim。

于 2012-04-17T22:59:52.297 回答