根据条件将列表切成子列表

时间:2018-09-28 08:34:08

标签: python python-3.x list

我想分割以下数字列表:

num_list = [97, 122, 99, 98, 111, 112, 113, 100, 102] 

进入多个子列表。切片的条件是每个子列表中的数字应按升序排列。

因此最终结果将如下所示:

 list_1 = [97, 122]
 list_2 = [99]
 list_3 = [98, 111, 112, 113]
 list_4 = [100, 102]

有人可以帮我解决这个问题吗?非常感谢

4 个答案:

答案 0 :(得分:6)

不建议创建可变数量的变量。请改用列表或字典列表。这是一个dict和一个生成器函数的示例:

from itertools import islice, zip_longest

def yield_lists(L):
    x = []
    for i, j in zip_longest(L, islice(L, 1, None), fillvalue=L[-1]):
        x.append(i)
        if i > j:
            yield x
            x = []
    yield x

num_list = [97, 122, 99, 98, 111, 112, 113, 100, 102]

res = dict(enumerate(yield_lists(num_list), 1))

恢复:

{1: [97, 122],
 2: [99],
 3: [98, 111, 112, 113],
 4: [100, 102]}

例如,通过res[2]访问第二个列表。

答案 1 :(得分:4)

这是一种单线性Numpythonic方法:

np.split(arr, np.where(np.diff(arr) < 0)[0] + 1)

或者类似的方法来处理numpy代码,但效率较低:

from operator import sub
from itertools import starmap
indices = [0] + [
                  i+1 for i, j in enumerate(list(
                        starmap(sub, zip(num_list[1:], num_list)))
                    ) if j < 0] + [len(num_list)
                ] + [len(num_list)]

result = [num_list[i:j] for i, j in zip(indices, indices[1:])]

演示:

# Numpy
In [8]: np.split(num_list, np.where(np.diff(num_list) < 0)[0] + 1)
Out[8]: 
[array([ 97, 122]),
 array([99]),
 array([ 98, 111, 112, 113]),
 array([100, 102])]

# Python
In [42]: from operator import sub

In [43]: from itertools import starmap

In [44]: indices = [0] + [i+1 for i, j in enumerate(list(starmap(sub, zip(num_list[1:], num_list)))) if j < 0] + [len(num_list)]

In [45]: [num_list[i:j] for i, j in zip(indices, indices[1:])]
Out[45]: [[97, 122], [99], [98, 111, 112, 113], [100, 102]]

说明:

使用np.diff(),您可以获取每个项目与下一个项目(直到最后一个元素)之间的差异。然后,您可以使用numpy的矢量化性质来获取该差异为负的位置的索引,这可以通过简单比较和np.where()来完成。最后,您只需将索引传递到np.split()即可根据这些索引拆分数组。

答案 2 :(得分:2)

我已经快速编写了一种方法来执行此操作,我相信还有更有效的方法,但这至少有效:

num_list =[97, 122, 99, 98, 111, 112, 113, 100, 102]

arrays = [[num_list[0]]] # array of sub-arrays (starts with first value)
for i in range(1, len(num_list)): # go through each element after the first
    if num_list[i - 1] < num_list[i]: # If it's larger than the previous
        arrays[len(arrays) - 1].append(num_list[i]) # Add it to the last sub-array
    else: # otherwise
        arrays.append([num_list[i]]) # Make a new sub-array 
print(arrays)

希望这对您有所帮助:)

答案 3 :(得分:2)

这里所有不错的解决方案。也许对于某些人来说这会更容易理解?

def increasing(a, b):
    return a < b

def seq_split(lst, cond):
    sublst = [lst[0]]
    for item in lst[1:]:
        if cond(sublst[-1], item):
            sublst.append(item)
        else:
            yield sublst
            sublst = [item]
    if sublst:
        yield sublst

list(seq_split(num_list, increasing))