在Python中 如果有
[1,2,3,4,1,2,3,1,2,1]
列表, 我希望在像这样缩小尺寸时拆分列表
[1,2,3,4], [1,2,3], [1,2], [1]
我该如何编码?
答案 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
现在,我们可以使用groupby
与apply
一起创建一个新系列,将这些子列表作为行。我们正在从上面对新创建的分组术语进行分组,并将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.gt
或int.__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 强>
对于大多数情况来说,这是一种大规模的过度杀伤,所以不要这样做。我只是有一些乐趣,但这里的代码在技术上解决了你的问题。如果你把课程放在某个地方的图书馆里,那么实际用法就是单行。