2009-09-23 47 views
1

有以下类型的循环:我如何重写这个循环中,更有效的方式在Python

a = range(10) 
b = [something] 
for i in range(len(a)-1): 
    b.append(someFunction(b[-1], a[i], a[i+1])) 

但是for循环是杀死了大量的性能。我试图编写一个Windows生成器来给我2个元素的所有时间,但它仍然需要明确的for-loop到最后。有没有办法让这个更短,更高效的pythonic方式?

谢谢

编辑:我忘了b中的元素..对不起家伙。然而,我以前的问题的解决方案对我也有其他问题非常有帮助。谢谢。

回答

8

考虑这个

def make_b(a, seed): 
    yield seed 
    for a,b in zip(a[:-1], a[1:]): 
     seed= someFunction(seed, a, b) 
     yield seed 

它可以让你做到这一点

a = xrange(10) 
b= list(make_b(a,something)) 

注意,你可以经常使用这个:

b = make_b(a) 

而不是实际创建b作为列表。 b作为发电机功能,为您节省大量的存储(和一些时间),因为你未必真的需要在首位list对象。通常,你只需要一些可迭代的东西。

同样,对于a。这并不一定是一个list,只是某种迭代 - 就像一个yield语句生成功能。

+0

它更快,使这个列表理解? – leon 2009-09-23 14:29:50

+0

您的解决方案很有帮助,我非常感谢。但是,我错过了原来的问题中的东西..你可以再看一遍吗?非常感谢! – leon 2009-09-23 15:04:53

+0

在我的循环中,b的新元素指向b本身(由b [-1])。为此,我认为你的解决方案是不正确的。 – leon 2009-09-23 15:20:26

4

为了您最初阐明了对输入序列下面的工作的映射功能的问题,是关于有效率,因为它得到停留在Python土地的同时。

from itertools import tee 

a = range(10) 
a1, a2 = tee(a) 
a2.next() 
b = map(someFunction, a1, a2) 

至于你需要访问前一次迭代的结果扩大的问题 - 这种内心状态的出现在功能概念展开。但是Python不包括展开结构,和一个很好的理由为循环是在这种情况下更具有可读性,最有可能更快了。至于使它变得更加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])) 

如果循环开销确实是一个问题,那么someFunction必须是非常简单的东西。在这种情况下,它可能是最好写在一个更快的语言的整个循环,如C.

2

一些外环或其他会永远存在,但一个可能性,即可以减少开销是:

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 

用作:

b.extend(generate(a, b[-1])) 
0

尝试是这样的:

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

另外:

  • 从itertools使用功能应 是有用的还(较早的帖子)
  • 也许你可以重写someFunction和使用地图,而不是名单 理解
相关问题