2013-07-12 31 views
0

我創建的對象來自一個相當大的txt文件。我的代碼工作正常,但需要很長時間才能運行。這是因爲我首先要找的元素沒有排序,也沒有(必然)唯一。例如,我正在查找可能在文件中使用過兩次的數字代碼,但可能位於第一行和最後一行。我的想法是檢查某個代碼的使用頻率...Python:如何加快創建對象?

counter=collections.Counter([l[3] for l in self.body]) 

...然後循環訪問計數器。高級:如果只有在您不必遍歷整個文件時才使用代碼。然而,你被困在很多迭代中,這使得這個過程真的很慢。

所以我的問題確實是:我該如何改進我的代碼?另一個想法當然是首先處理數據。但是這可能也需要很長時間。

的關鍵部分是這個方法:

def get_pc(self): 
    counter=collections.Counter([l[3] for l in self.body]) 
    # This returns something like this {'187':'2', '199':'1',...} 

    pcode = [] 

    #loop through entries of counter 
    for k,v in counter.iteritems(): 
     i = 0 
     #find post code in body 
     for l in self.body: 
      if i == v: 
       break 
      # find fist appearence of key 
      if l[3] == k: 
       #first encounter... 
       if i == 0: 
        #...so create object 
        self.pc = CodeCana(k,l[2]) 
        pcode.append(self.pc) 
       i += 1 
       # make attributes 
       self.pc.attr((l[0],l[1]),l[4]) 
      if v <= 1: 
       break 
    return pcode 

我希望的代碼足以說明問題。如果沒有,請告訴我,我會擴展提供的信息。

+0

對於初學者:使用生成器表達式而不是列表理解。你不需要中間人名單。 'Counter(l [3] for self inbody)'就足夠了。 –

+0

爲什麼在循環中設置'self.pc'?它將很快被下一個'CodeCana'對象替代。爲什麼地方不會在這裏? –

+0

數據是什麼樣的? –

回答

2

您正在循環播放body太多次。收起這個成一個循環,並跟蹤字典的CodeCana物品來代替:

def get_pc(self): 
    pcs = dict()  
    pcode = [] 

    for l in self.body: 
     pc = pcs.get(l[3]) 
     if pc is None: 
      pc = pcs[l[3]] = CodeCana(l[3], l[2]) 
      pcode.append(pc) 
     pc.attr((l[0],l[1]),l[4]) 

    return pcode 

計數的所有項目第一,然後試圖限制由多次遍歷body同時仍然在所有不同類型的循環的項目有點失敗的目的...

你可能要考慮給名稱l各種指數。您可以使用元組拆包:

for foo, bar, baz, egg, ham in self.body: 
    pc = pcs.get(egg) 
    if pc is None: 
     pc = pcs[egg] = CodeCana(egg, baz) 
     pcode.append(pc) 
    pc.attr((foo, bar), ham) 

但建設bodya namedtuple-based class代碼文件和調試更會有幫助。

+0

它的確如此。有點卡住了。謝謝你的想法。 – LarsVegas

+0

感謝您的有益建議。 – LarsVegas