首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在python列表中查找增长长度的子列表

在python列表中查找增长长度的子列表
EN

Stack Overflow用户
提问于 2022-06-25 08:18:09
回答 3查看 78关注 0票数 -1

假设n=6(列表长度) lis = 3, 2, 3, 4, 3, 1

我需要在最后一个元素之前有最大增长长度的子列表列表。它是:[3], [2, 3], [4, 3, 1]

如果lis = 3,2,3,4,3为5个元素,则结果应为[3,2,3],因为前面没有三个元素

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2022-06-25 08:56:24

您可以使用:

代码语言:javascript
复制
def cut(l):
    i = 1
    pos = 0
    out = []
    while pos<len(l)-i+1:
        out.append(l[pos:pos+i])
        pos += i
        i += 1
    return out

cut([1,2,3,4,5,6,7,8,9,10,11])

产出:

代码语言:javascript
复制
[[1], [2, 3], [4, 5, 6], [7, 8, 9, 10]]

变体

其他方法的乐趣,如果我们不想测试的位置相对于结束在每一步。

第一个n个整数的和是x = n*(n+1)/2,我们可以计算,给定xn = int((math.sqrt(1+8*x)-1)/2)。这使我们能够直接知道有多少步骤:

代码语言:javascript
复制
# function to calculate the number of steps from the list length
def nb(x):
    import math
    return int((math.sqrt(1+8*x)-1)/2)
# nb(11) -> 4

def cut(l):
    pos = 0
    out = []
    for i in range(1, nb(len(l))+1):
        out.append(l[pos:pos+i])
        pos += i
    return out

cut([1,2,3,4,5,6,7,8,9,10,11])
票数 1
EN

Stack Overflow用户

发布于 2022-06-25 08:54:44

最舒适的解决方案:

代码语言:javascript
复制
np.split(lis, np.cumsum(range(len(lis))))

或者,用一些数学在这里:

代码语言:javascript
复制
np.split(lis, np.cumsum(range(int(np.ceil(np.sqrt(9/4 + 2*len(lst)) - 3/2)))))

解决方案,没有numpy:

代码语言:javascript
复制
[lst[sum(range(i+1)):sum(range(i+1)) + i + 1] for i in range(len(lst)) if len(lst[sum(range(i+1)):])>=i]

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

稍微短一点

代码语言:javascript
复制
[lst[l:l + i + 1] for i in range(len(lst)) if len(lst[(l := sum(range(i+1))):])>=i]

正如@mozway所提到的,由于对累积和的反复评估,这种方法速度较慢。人们可以改变这种做法:

代码语言:javascript
复制
l = 0
[lst[l:(l := l + i + 1)] for i in range(len(lst)) if len(lst[l:])>=i]

这是有点麻烦,但很有趣,尽管如此。

现在,利用这里的一些基本数学,我们可以得到相当快的

代码语言:javascript
复制
[lst[i*(i+1)//2 : (i+1)*(i+2)//2] for i in range(int(np.ceil(np.sqrt(9/4 + 2*len(lst)) - 3/2)))]

起初,这是我的回答:

代码语言:javascript
复制
[lst[i:2*i + 1] for i in range(len(lst)) if len(lst[i:])>=i]

但这从以前使用过的项目开始。

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

票数 1
EN

Stack Overflow用户

发布于 2022-06-25 13:21:40

只是用一些itertools抛出另一个选项..。因此,它将适用于任何可以迭代的东西,而不仅仅是支持切片的对象。

代码语言:javascript
复制
from itertools import count, islice

# Make a generator so take the first N elements of what's remaining each time until we get an empty list...
chunk_iter = iter(lambda it=iter(lis), size=count(1): list(islice(it, next(size))), [])
# Filter out those to drop entries not matching the expected length (eg: drop last element if needed)
valid_chunks = (el for n, el in enumerate(chunk_iter, 1) if len(el) == n)

# Iterate over the above or optionally materialise into a list of lists...
# (and ignoring the very last entry if it's not the length of the number we're expecting)
res = list(valid_chunks)

不过,将其封装到一个更易读的生成器函数中可能要好得多,例如:

代码语言:javascript
复制
def f(iterable):
    it = iter(iterable)
    for size in count(1):
        val = list(islice(it, size))
        if len(val) != size:
            break
        yield val
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72752308

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档