在Python中,有没有办法在迭代的每个项目上调用方法?

Tha*_*all 3 python iteration methods premature-optimization

可能重复:
在python中是否有没有结果的地图?

当我想快速/有效地在迭代所包含的每个项目上调用就地方法时,我经常会遇到程序中的情况.(很快意味着for循环的开销是不可接受的).当我想调用draw()每个Sprite对象时,一个很好的例子是精灵列表.

我知道我可以这样做:

[sprite.draw() for sprite in sprite_list]

但我觉得列表理解被滥用,因为我没有使用返回的列表.这同样适用于该map功能.石头我过早优化,但我也不希望返回值的开销.

我想知道的是,如果在Python中有一个方法可以让我做我刚才解释的方法,也许就像我在下面建议的假设函数:

do_all(sprite_list, draw)

aba*_*ert 9

你总是可以编写自己的do_all函数:

def do_all(iterable, func):
    for i in iter(iterable):
       func(i)
Run Code Online (Sandbox Code Playgroud)

然后随时调用它.

使用显式for循环确实没有性能问题.

有或使用列表理解性能问题map,但只有在建立结果列表.显然,如果你必须在整个过程中建立一个500M的列表,那么迭代超过500M的项目将会慢得多.

值得指出的是,这几乎肯定不会出现像绘制精灵列表之类的东西.你没有500M精灵来绘制.如果你这样做,它可能比创建一个500M的无副本列表要花很多时间.在大多数合理的情况下,你需要对500M对象做同样非常简单的事情,有更好的解决方案,比如切换到numpy.但是有一些可以想象的情况可能会出现这种情况.

简单的方法是使用生成器表达式或itertools.imap(或者,在Python 3中map),然后通过编写dispose函数来处置值.一种可能性:

def dispose(iterator):
    for i in iterator:
        pass
Run Code Online (Sandbox Code Playgroud)

然后:

dispose(itertools.imap(Sprite.draw, sprite_list))
Run Code Online (Sandbox Code Playgroud)

你甚至可以定义do_all为:

def do_all(iterable, func):
    dispose(itertools.imap(func, iterable))
Run Code Online (Sandbox Code Playgroud)

如果您为了清晰或简单而这样做,我认为这是错误的.for循环版本非常容易阅读,而且这个版本看起来像是在试图用错误的函数名和语法编写Haskell.

如果你是为了表现那么......好吧,如果有一个真实的表演情况,这很重要(这似乎不太可能),你可能想要玩一堆不同的潜在实现dispose,并且可能将其dispose移回到do_all以避免额外的函数调用,甚至可能在C中实现整个事物(借用stdlib的itertools.c中的快速迭代代码).

或者,更好pip install more-itertools,然后使用more_itertools.consume.对于它的价值,当前版本只是做了collections.deque(iterator, maxlen=0),并且在针对自定义C实现的测试中,它的速度慢了不到1%(非常小的迭代器 - 我的系统上的截止值为19),所以它可能不值得实现C.但如果有人这样做,或者某些未来的Python(或PyPy)提供了更快的实现方法,那么more-itertools在您发现它并更改代码之前,它可能会被添加进去.

  • 并不是所有人都在乎,但我认为我找到了最快的方式来消费迭代器而不做任何事情.看到答案. (2认同)

Mat*_*att 7

假设sprite_list是Sprite对象的列表,您可以这样做:

map(Sprite.draw, sprite_list)
Run Code Online (Sandbox Code Playgroud)

这将在每个项目上调用Sprite.draw(),sprite_list其中与您发布的列表推导基本相同.如果您不想创建列表,可以使用for循环:

for sprite in sprite_list:
    sprite.draw()
Run Code Online (Sandbox Code Playgroud)

  • map的问题是它还返回结果列表,我特别不需要/想要.我提到它是我认识工作的方式之一,但不是理想的. (4认同)