如何拆分Python列表并按升序创建新列表?

时间:2017-11-23 05:12:36

标签: python list

在Python中 如果有

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

列表, 我希望在像这样缩小尺寸时拆分列表

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

我该如何编码?

4 个答案:

答案 0 :(得分:11)

您可以使用Pandas分三行:

import pandas as pd
s = pd.Series([1,2,3,4,1,2,3,1,2,1])
s.groupby(s.diff().lt(0).cumsum()).apply(list).tolist()

输出:

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

详细说明其工作原理:

首先从列表中创建一个pandas系列,然后使用pd.Series中的diff方法获取与之前值的差异:

s.diff()

0    NaN
1    1.0
2    1.0
3    1.0
4   -3.0
5    1.0
6    1.0
7   -2.0
8    1.0
9   -1.0
dtype: float64

负值表示新“子”列表的开头。因此,我们使用lt(0)标记那些应该开始新“子”列表的记录。

s.diff().lt(0)

0    False
1    False
2    False
3    False
4     True
5    False
6    False
7     True
8    False
9     True
dtype: bool

接下来,我们将使用cumsum创建分组术语。 cumsum只会在True时递增,所以彼此相邻的所有falses都会获得相同的值,然后True递增并且下一组falses获得该新值,直到下一个True。

s.diff().lt(0).cumsum()

0    0
1    0
2    0
3    0
4    1
5    1
6    1
7    2
8    2
9    3
dtype: int32

现在,我们可以使用groupbyapply一起创建一个新系列,将这些子列表作为行。我们正在从上面对新创建的分组术语进行分组,并将python list应用于该组中的那些值,从而创建“子”列表。

s.groupby(s.diff().lt(0).cumsum()).apply(list)

0    [1, 2, 3, 4]
1       [1, 2, 3]
2          [1, 2]
3             [1]
dtype: object

最后,我们在系列中应用tolist方法将系列作为列表返回。

s.groupby(s.diff().lt(0).cumsum()).apply(list).tolist()

最终输出:

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

答案 1 :(得分:2)

这可能是您正在寻找的算法 -

-c

它输出一个排序列表列表 -

a=[1,2,3,4,1,2,3,1,2,1] b=[] c=[] for i in range(len(a)-1): b.append(a[i]) if a[i] > a[i+1]: c.append(b) b=[] print(c)

如果有帮助,请告诉我。

答案 2 :(得分:2)

如果您希望在下一个数字少于上一个数字时拆分列表,那么这可能会有所帮助:

arr = [1,2,3,4,1,2,3,1,2,1]
b = []
start = 0
for i in range(len(arr)):
  if(arr[i] < arr[i-1]):
    b.append(arr[start:i])
    start = i
b.append(arr[start:])
print(b)

输出: [[1, 2, 3, 4], [1, 2, 3], [1, 2], [1]]

希望这有帮助。

答案 3 :(得分:2)

为了好玩,我想看看你是否可以将文档中给出的代码重新编写为itertools.groupby的示例实现,以便以一般方式满足您的需求。结果是一个生成器,其元素是表示子列表的子生成器。确定何时拆分是由两个变量的用户定义函数完成的,这两个变量接受每个连续的相邻元素对,并在它们位于不同的组中时返回True

from collections import deque

class splitby:
    # [''.join(s) for s in splitby('AAAABBBCCDAABBB', operator.eq)] --> ['AAAA', 'BBB', 'CC', 'D', 'AA', 'BBB']
    def __init__(self, iterable, splitter):
        self.splitfunc = splitter
        self.it = iter(iterable)
        self.segment = None
    def __iter__(self):
        return self
    def __next__(self):
        if self.segment:
            deque(self.segment, maxlen=0)
            if self.segment is None:
                raise StopIteration
        else:
            self.curvalue = next(self.it)
        self.segment = self._splitter()
        return self.segment
    def _splitter(self):
        split = False
        while not split:
            yield self.curvalue
            prev = self.curvalue
            try:
                self.curvalue = next(self.it)
            except StopIteration:
                self.segment = None
                return
            split = self.splitfunc(prev, self.curvalue)

如果您的列表只包含整数,则整个内容可以应用于您的输入列表,其分割符函数为operator.gtint.__gt__。在list中合适的包装不仅会正确使用元素,还会使输出与您的问题相符:

from operator import gt

x = [1, 2, 3, 4, 1, 2, 3, 1, 2, 1]
[list(s) for s in splitby(x, gt)]

结果是:

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

以下是IDEOne链接:https://ideone.com/UW483U

<强> TL; DR

对于大多数情况来说,这是一种大规模的过度杀伤,所以不要这样做。我只是有一些乐趣,但这里的代码在技术上解决了你的问题。如果你把课程放在某个地方的图书馆里,那么实际用法就是单行。