2017-05-07 66 views
10

我目前文件正在與超過200萬線。我已將行分隔爲元素列表(例如:[a,b,c,d] = 1行,單詞分隔)。Python的循環優化

我嘗試使用下面的代碼要經過所有行:

for a in aud: 
    for esps in final: 
     if a[0] in final[esps]: 
      a[0] = esps 

在第一個for循環,我指的是200萬條+線。在第二個for循環中,它通過一個帶有2010鍵的字典,每個鍵可能至少有50個相應的值。我想在等於字典中的值的行中找到a[0]元素。如果它們匹配,則將所選行中的a[0]元素更改爲字典的鍵值。

的問題是,這種代碼需要年齡運行,我不明白太多(沒有),有關優化,以及如何以更快的速度運行此。 如果有人能告訴我如何更快地做這樣的事情,我會非常感謝。

+0

嗯,你只限於一臺電腦?我想你可以用幾個工人來做到這一點。即使只使用一臺計算機,也可以使用多核CPU創建多個工作人員 –

+0

在沒有任何示例數據的情況下,要解決您的實際問題有點難。每個「最終」字典字符串中的所有50個密鑰都是? – jsbueno

+0

在迭代它的時候會不會有一個變異對象的副作用? – pylang

回答

24

當你有「大」的東西貫穿,類似這樣的,關鍵要得到的東西去快是「減少算法的複雜性」 - 也就是說,避免依賴於任何數據如果可能集的大小任何操作。

在你給的例子,你執行,爲您的每一個百萬行的50×2000線性搜索 - 這是一個很大!問題是,如果每個final[esps]的是一個列表,Python的執行在這50個值的線性搜索 - 與運營商in

既然你提到你正在從文件中讀取你的值,我不得不假設012 [0]和final行中的元素都是字符串 - 但這也適用於數字。

第一個非常簡單的優化,是簡單地改變從列表對final字典行到set秒 - 從in操作者變更了比賽用set從是線性的,以在恆定的時間(從O(m)至O(1)) - 所以,你基本上是50倍,如果在你的榜樣運行的代碼之前削減你的搜索時間,你這樣做:

for key in final: 
    final[key] = set(final[key]) 

但你依然表現在每一個2010的線性搜索鑰匙final。更改爲不斷尋求的方法是創建一個顛倒的字典 - 其中每50個值的final點的一排按鍵esp代替。然後,您只需在此反轉字典中使用[0]作爲關鍵字 - 並且您正在替換100000個項目(2000 x 50)中的線性搜索,以便在字典中以恆定時間進行搜索;

這是很容易做到 - 只要改變你的代碼:

rfinal = {} 
for esp, values in final.items(): 
    for value in values: 
     rfinal[value] = esp 


for a in aud: 
    if a[0] in rfinal: 
     a[0] = rfinal[a[0]] 
    else: 
     # code for when there is no match for a[0] 
     ... 
+2

這個例子改變了一切。從超過1小時沒有完成...到僅僅幾秒鐘。這非常有幫助!通過我的工作和理解未來如何優化代碼。謝謝你200萬次以上! – Targaryel

+0

它只是大約100。在這種情況下快000倍:-) - 如果有效,請記得將答案標記爲已接受。 – jsbueno

+2

實踐這種優化問題的好地方是https://projecteuler.net/ – jsbueno