[英]how to rewrite this loop in a more efficient way in python
I have a loop of the following type: 我有以下类型的循环:
a = range(10)
b = [something]
for i in range(len(a)-1):
b.append(someFunction(b[-1], a[i], a[i+1]))
However the for-loop is killing a lot of performance. 但是,for循环会破坏很多性能。 I have try to write a windows generator to give me 2 elements everything time but it still require explicit for-loop in the end.
我试图编写一个Windows生成器,以便每次都给我2个元素,但最后仍然需要显式的for循环。 Is there a way to make this shorter and more efficient in a pythonic way?
有没有办法用pythonic方法使它更短,更有效?
Thanks 谢谢
edit: I forgot the element in b.. sorry guys. 编辑:我忘记了b ..对不起,各位。 However the solution to my previous problem is very helpful in other problem I have too.
但是,解决我以前的问题对我遇到的其他问题也很有帮助。 Thanks.
谢谢。
Consider this 考虑一下
def make_b( a, seed ):
yield seed
for a,b in zip( a[:-1], a[1:] ):
seed= someFunction( seed, a, b )
yield seed
Which lets you do this 这让你做到这一点
a = xrange(10)
b= list(make_b(a,something))
Note that you can often use this: 请注意,您经常可以使用以下命令:
b = make_b(a)
Instead of actually creating b
as a list. 而不是实际创建
b
作为列表。 b
as a generator function saves you considerable storage (and some time) because you may not really need a list
object in the first place. b
作为生成器函数可以节省大量的存储空间(并节省一些时间),因为您可能根本不需要list
对象。 Often, you only need something iterable. 通常,您只需要可迭代的内容。
Similarly for a
. 同样
a
。 It does not have to be a list
, merely something iterable -- like a generator function with a yield
statement. 它不必是
list
,而可以是可迭代的东西,例如带有yield
语句的生成器函数。
For your initially stated problem of mapping a function over pairs of an input sequence the following will work, and is about as efficient as it gets while staying in Python land. 对于您最初提出的在输入序列对上映射函数的问题,下面的方法将起作用,并且效率与停留在Python领域中时一样高效。
from itertools import tee
a = range(10)
a1, a2 = tee(a)
a2.next()
b = map(someFunction, a1, a2)
As for the expanded problem where you need to access the result of the previous iteration - this kind of inner state is present in the functional concept unfold. 至于需要访问先前迭代结果的扩展问题-这种内部状态在功能概念中存在。 But Python doesn't include an unfold construct, and for a good reason for loops are more readable in this case and most likely faster too.
但是Python不包含展开结构,因此在这种情况下,循环更具可读性,而且很有可能也更快。 As for making it more Pythonic, I suggest lifting the pairwise iteration out to a function and create an explicit loop variable.
至于使其更具Pythonic性,我建议将成对迭代提升为一个函数并创建一个显式循环变量。
def pairwise(seq):
a, b = tee(seq)
b.next()
return izip(a, b)
def unfold_over_pairwise(unfolder, seq, initial):
state = initial
for cur_item, next_item in pairwise(seq):
state = unfolder(state, cur_item, next_item)
yield state
b = [something]
b.extend(unfold_over_pairwise(someFunction, a, initial=b[-1]))
If the looping overhead really is a problem, then someFunction must be something really simple. 如果循环开销确实是个问题,那么someFunction必须非常简单。 In that case it probably is best to write the whole loop in a faster language, such as C.
在这种情况下,最好以更快的语言(例如C)编写整个循环。
Some loop or other will always be around, but one possibility that might reduce overhead is: 总是会出现一些循环,但可能会减少开销的一种可能性是:
import itertools
def generate(a, item):
a1, a2 = itertools.tee(a)
next(a2)
for x1, x2 in itertools.izip(a1, a2):
item = someFunction(item, x1, x2)
yield item
to be used as: 用作:
b.extend(generate(a, b[-1]))
Try something like this: 尝试这样的事情:
a = range(10)
b = [something]
s = len(b)
b+= [0] * (len(a) - 1)
[ b.__setitem__(i, someFunction(b[i-1], a[i-s], a[i-s+1])) for i in range(s, len(b))]
Also: 也:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.