python-3.x 如何将列表拆分为长度在2到4之间的子列表?

w8f9ii69  于 2023-03-13  发布在  Python
关注(0)|答案(3)|浏览(141)

我想写一个函数,将列表拆分成长度在2到4之间的子列表,不能多也不能少。
例如,这个列表["a","a","a","a","a","a","a","a","a"]可以变成[["a","a","a","a"],["a","a","a"],["a","a"]][["a","a","a"],["a","a","a","a"],["a","a"]]
我写了这个函数:

def split_list(lst):
    result = []
    sublist = []
    for i in range(len(lst)):
        sublist.append(lst[i])
        if len(sublist) == 4 or (len(sublist) == 2 and i == len(lst)-1):
            result.append(sublist)
            sublist = []
        elif len(sublist) == 3 and i == len(lst)-1:
            result.append(sublist)
    return result

但是["a","a","a","a","a","a","a","a","a"]的输出是[['a', 'a', 'a', 'a'], ['a', 'a', 'a', 'a']],这是错误的。
对于少于三个值的列表,它必须输出该列表:例如["a","a"]不能更改
我怎么能这么做?

qnyhuwrf

qnyhuwrf1#

有多种方法可以实现这一点,下面是一个算法:
1.如果子列表的长度为4,则将其添加到结果中,并将子列表重置为[]。
1.如果子列表的长度为3,并且只剩下2个项,则添加子列表,这样我们就不会在最后一个子列表中只剩下一个项
1.在循环结束时,将最终的子列表添加到结果中(如果它不为空)
这样,我们将从尽可能多的长度为4的项目开始,而不允许任何项目集的项目少于2个。

def split_list(lst):
    result = []
    sublist = []
    for i in range(len(lst)):
        sublist.append(lst[i])
        if len(sublist) == 4:
            result.append(sublist)
            sublist = []
        elif len(sublist) == 3 and i == len(lst)-3:
            # there are only two items after this element, so add the
            # sublist to the result now
            result.append(sublist)
            sublist = []
    if sublist:
        result.append(sublist)
    return result

让我们用长度从0到14的列表来测试它。

for i in range(15):
    print(split_list('a'*i))

给出的结果

[]
[['a']]
[['a', 'a']]
[['a', 'a', 'a']]
[['a', 'a', 'a', 'a']]
[['a', 'a', 'a'], ['a', 'a']]
[['a', 'a', 'a', 'a'], ['a', 'a']]
[['a', 'a', 'a', 'a'], ['a', 'a', 'a']]
[['a', 'a', 'a', 'a'], ['a', 'a', 'a', 'a']]
[['a', 'a', 'a', 'a'], ['a', 'a', 'a'], ['a', 'a']]
[['a', 'a', 'a', 'a'], ['a', 'a', 'a', 'a'], ['a', 'a']]
[['a', 'a', 'a', 'a'], ['a', 'a', 'a', 'a'], ['a', 'a', 'a']]
[['a', 'a', 'a', 'a'], ['a', 'a', 'a', 'a'], ['a', 'a', 'a', 'a']]
[['a', 'a', 'a', 'a'], ['a', 'a', 'a', 'a'], ['a', 'a', 'a'], ['a', 'a']]
[['a', 'a', 'a', 'a'], ['a', 'a', 'a', 'a'], ['a', 'a', 'a', 'a'], ['a', 'a']]
6ljaweal

6ljaweal2#

您可以一次在较高边界上拆分输入列表,然后检查最后一个项目/子列表是否适合较低边界(以覆盖主要需求):

def split_nsize(lst, low=2, high=4):
    if len(lst) <= high:  # base case
        return lst

    res = [lst[i: i + high] for i in range(0, len(lst), high)]
    before_last, last = res[-2], res[-1]
    if len(last) < low:  # ensure the last sublist fits the bounds
        res[-1] = [before_last[-1]] + last  # borrow value from before-last item
        res[-2] = before_last[: high - 1]  # cut before-last item
    return res

测试:
一个一个一个一个一个x一个一个二个一个x一个一个三个一个x一个一个x一个四个一个

niknxzdl

niknxzdl3#

检查完长度小于4的列表后,你可以用传统的方式通过分片来构建一个列表列表。然后,你只关心最后一个子列表。如果它的长度为1,你只需要适当地调整最后两个条目。如下所示:

def split_list(_list):
    if len(_list) < 4:
        return [_list]
    result = [_list[i:i+4] for i in range(0, len(_list), 4)]
    if len(result[-1]) == 1:
        result[-1] = [result[-2][-1]] + result[-1]
        result[-2] = result[-2][:-1]
    return result

相关问题