2017-02-14 58 views
4

我有一個像拆分列表爲增加序列使用itertools

[1,2,3,4,5,2,3,4,1,2] 

混合序列的名單我想知道我該如何使用itertools到列表分成增加序列切割清單在下降點。例如上述將

[[1, 2, 3, 4, 5], [2, 3, 4], [1, 2]] 

這已經通過注意到序列降低在2所以我們切割第一比特那裏,另一減少爲一個切割再次那裏獲得的輸出。

另一個例子是序列

[3,2,1] 

輸出應該是

[[3], [2], [1]] 

倘若給定的順序增加我們返回相同的序列。例如,

[1,2,3] 

返回相同的結果。即

[[1, 2, 3]] 

對於重複的名單像

[ 1, 2,2,2, 1, 2, 3, 3, 1,1,1, 2, 3, 4, 1, 2, 3, 4, 5, 6] 

輸出應該是

[[1, 2, 2, 2], [1, 2, 3, 3], [1, 1, 1, 2, 3, 4], [1, 2, 3, 4, 5, 6]] 

我做了什麼來實現這一目標是定義下列函數

def splitter (L): 
    result = [] 
    tmp = 0 
    initialPoint=0 
    for i in range(len(L)): 
     if (L[i] < tmp): 
      tmpp = L[initialPoint:i] 
      result.append(tmpp) 
      initialPoint=i 
     tmp = L[i] 
    result.append(L[initialPoint:]) 
    return result 

的功能正在工作g 100%,但我需要的是對itertools做同樣的事情,這樣我就可以提高代碼的效率。有沒有辦法用itertools包來做到這一點,以避免顯式循環?

+0

這是**工作代碼**,您認爲可以改進,請考慮[codereview.se]。 – jonrsharpe

+0

是的。代碼正在工作。我在想也許itertools軟件包有一些可以幫助改進它 –

回答

5

隨着numpy,你可以使用numpy.split,這需要索引作爲拆分立場;因爲要分割,其中值降低,則可以使用numpy.diff計算差值,並檢查該差小於零,並使用numpy.where檢索相應的指數,在問題的最後一種情況的例子:

import numpy as np 
lst = [ 1, 2,2,2, 1, 2, 3, 3, 1,1,1, 2, 3, 4, 1, 2, 3, 4, 5, 6] 
np.split(lst, np.where(np.diff(lst) < 0)[0] + 1) 

# [array([1, 2, 2, 2]), 
# array([1, 2, 3, 3]), 
# array([1, 1, 1, 2, 3, 4]), 
# array([1, 2, 3, 4, 5, 6])] 
+0

我認爲這解決了我的需求。非常感謝你 –

1

假設你原來的輸入數組:

a = [1, 2, 3, 4, 5, 2, 3, 4, 1, 2] 

首先找到在哪裏劈叉應出現的地方:

p = [ i+1 for i, (x, y) in enumerate(zip(a, a[1:])) if x > y ] 

然後創建切片爲每個這樣分割:

print [ a[m:n] for m, n in zip([ 0 ] + p, p + [ None ]) ] 

這將打印:

[[1, 2, 3, 4, 5], [2, 3, 4], [1, 2]] 

我建議使用更多的講的名字比pnm等。;-)

2

Psidom已經爲你覆蓋了一個很好的答案,但另一個NumPy解決方案將使用scipy.signal.argrelmax來獲取本地最大值,然後np.split

from scipy.signal import argrelmax 
arr = np.random.randint(1000, size=10**6) 
splits = np.split(arr, argrelmax(arr)[0]+1)