2013-04-18 128 views
2

現在我用一個列表來存儲改變字符串,並用。加入()字符串連接性能

def applyCoder(text, coder): 
    l = [] 
    for i in text: 
     if i in coder: 
      l.append(coder[i]) 
     else: 
      l.append(i) 
    return ''.join(l) 

# example output, shifts all letters by 3 in a string 
# print applyCoder("Hello, world!", buildCoder(3)) 
# buildCoder(3) returns dictionary, e.g. {'A': 'D', ...} 
# >>> Khoor, zruog! 

是否有改變,並返回一個字符串更快的方法返回一個字符串?

+0

修復喲ur'return'語句 – jamylak

+0

完成這是一個錯字 – user2144553

回答

4

這應該是儘可能地快:

''.join([coder[i] if i in coder else i for i in text]) 

列表理解是比較for環,其承受很大的開銷在Python更加優化。我已經通過了列表理解,而不是''.join中的生成器,因爲它必須在加入之前預先知道輸入的長度。如果你給它一個發生器,它必須把它變成一個列表(這有點慢)。

實際上可以進一步簡化此,其中甚至更​​快此實際執行比上述方法更慢由於該方法調用

''.join([coder.get(i,i) for i in text]) 

時序:

def applyCoder(text, coder): 
    L = [] 
    for i in text: 
     if i in coder: 
      L.append(coder[i]) 
     else: 
      L.append(i) 
    return ''.join(L) 

def list_comp(text, coder): 
    return ''.join([coder[i] if i in coder else i for i in text]) 

def list_comp2(text, coder): 
    return ''.join([coder.get(i,i) for i in text]) 

from timeit import timeit 
from string import ascii_letters 
d = dict(zip(ascii_letters, ascii_letters[3:] + ascii_letters[-3:])) 


print timeit(stmt='applyCoder("Hello, world!", d)', 
      setup='from __main__ import applyCoder, d;') 

print timeit(stmt='list_comp("Hello, world!", d)', 
      setup='from __main__ import list_comp, d;')  

print timeit(stmt='list_comp2("Hello, world!", d)', 
      setup='from __main__ import list_comp2, d;') 

print timeit(stmt='applyCoder("Hello, world!"*10, d)', 
      setup='from __main__ import applyCoder, d;') 

print timeit(stmt='list_comp("Hello, world!"*10, d)', 
      setup='from __main__ import list_comp, d;') 


print timeit(stmt='list_comp2("Hello, world!"*10, d)', 
      setup='from __main__ import list_comp2, d;') 

結果:

''' Test 1 ''' 
5.0159105417 # applyCoder 
3.41502481461 # listcomp1 
4.76796932292 # listcomp2 

''' Test 2 ''' 
34.9718502631 # applyCoder 
22.0451702661 # listcomp1 
34.1682597928 # listcomp2 

看來,調用coder.get的方法完全否定了列表理解的優點。我的確預測它可能會比listcomp1慢,但我認爲它不會有太大的影響。無論如何,列表理解仍然獲勝。

更新: 如果修改list_comp2像這樣:

def list_comp2(text, coder): 
    coder_get = coder.get 
    return ''.join([coder_get(i,i) for i in text]) 

的時間顯着提高:

4.76796932292第一測試 - >3.95217394948

34.1682597928(第二次測試) - >27.1162974624

+0

+1的美麗pythonic代碼。 – Maroun

+0

平均:0.00015 vs 0.00011(你的)有10,000個電話。 – user2144553

+0

@ user2144553那些必須是微小的輸入,(我假設那些是秒),你可以試試更大的?另外,如果你可以告訴我兩個我的時間編輯:我會嘗試一些時間以及 – jamylak