Python 使用itertools将列表拆分为递增序列

Python 使用itertools将列表拆分为递增序列,python,numpy,itertools,Python,Numpy,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,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]
返回相同的结果。i、 e

[[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
def分离器(L):
结果=[]
tmp=0
初始点=0
对于范围内的i(len(L)):
如果(L[i]

该函数100%工作,但我需要的是使用itertools做同样的事情,以便提高代码的效率。有没有办法用itertools包来避免显式循环?

使用
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])]
将numpy导入为np
lst=[1,2,2,1,2,3,1,1,1,1,2,3,4,1,2,3,4,5,6]
np.split(lst,np.where(np.diff(lst)<0)[0]+1)
#[数组([1,2,2,2]),
#数组([1,2,3,3]),
#数组([1,1,1,2,3,4]),
#数组([1,2,3,4,5,6])]

假设您的原始输入数组:

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]]

我建议使用比
p
n
m
等更多的会说话的名字;-)

Psidom已经为您提供了一个很好的答案,但另一个NumPy解决方案是使用它获取局部最大值,然后
np.split

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

这是你认为可以改进的工作代码,是的。代码正在运行。我在想也许itertools软件包有助于改进它