2009-09-23 50 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和使用地圖,而不是名單 理解
相關問題