2017-01-06 514 views
2

我的問題是類似於這個previous SO question 我有一個非常大的數據列表(近1.2億個數據點),包含大量連續重複。我想刪除連續重複如下快速刪除連續重複python

list1 = [1,1,1,1,1,1,2,3,4,4,5,1,2] #This is 20M long! 
list2 =[another list of size len(list1)]#This is also 20M long! 
i = 0 
while i < len(list)-1: 
    if list[i] == list[i+1]: 
     del list1[i] 
     del list2[i] 
    else: 
     i = i+1 

並輸出應爲[1,2,3,4,5,1,2] 不幸的是,這是因爲在一個列表中刪除元件非常慢的本身就是一個緩慢的操作。有什麼辦法可以加速這個過程嗎?請注意,如上面的代碼所示,我還需要跟蹤索引i,以便我可以刪除list2中的相應元素。

回答

6

Python有這個groupby在你的庫:

>>> list1 = [1,1,1,1,1,1,2,3,4,4,5,1,2] 
>>> from itertools import groupby 
>>> [k for k,_ in groupby(list1)] 
[1, 2, 3, 4, 5, 1, 2] 

可以使用keyfunc說法,也處理,同時第二個列表調整它。

>>> list1 = [1,1,1,1,1,1,2,3,4,4,5,1,2] 
>>> list2 = [9,9,9,8,8,8,7,7,7,6,6,6,5] 
>>> from operator import itemgetter 
>>> keyfunc = itemgetter(0) 
>>> [next(g) for k,g in groupby(zip(list1, list2), keyfunc)] 
[(1, 9), (2, 7), (3, 7), (4, 7), (5, 6), (1, 6), (2, 5)] 

如果你想對那些再次拆分爲單獨的序列:

>>> zip(*_) # "unzip" them 
[(1, 2, 3, 4, 5, 1, 2), (9, 7, 7, 7, 6, 6, 5)] 
+1

幾個勝在這裏。首先,您使用標準庫而不是重寫代碼。 Itertools以C語言實現速度。最後,你並沒有試圖反覆修改列表。根據數據來自何處或你在做什麼,從發生器開始,首先避免20MB的列表或者將結果保存爲生成器可能會更有效。 –

+0

哇!我不敢相信我花了幾乎整整一天的時間。你的解決方案很快。當我的意思是快時,它將執行時間從兩小時減少到僅僅1分鐘!非常感謝。只是一個簡單的問題,當我在python解釋器中運行你的代碼時,它就起作用了。然而,在pyCharm中運行得到這個令人討厭的錯誤,沒有定義zip(* _)中的'_'。有任何想法嗎? –

+1

將列表理解的結果分配給一個變量,然後使用'zip(* result)'。我在解釋器中使用了一個快捷方式('_'指的是「上次評估結果」)。 – wim