Python: объединить все последовательные подсписки списка до тех пор, пока не будет выполнено условие

#python #python-2.7 #list

#python #python-2.7 #Список

Вопрос:

У меня есть список, содержащий элементы подсписков, которые выглядят следующим образом:

 li = [[1],[2,3,4],[5,6],[7,8,9,10],[11],[12],[13],[14,15,16]]
  

Я хотел бы объединить все подсписки, которые короче определенного значения limit , со следующими подсписками, пока длина нового подсписка не станет >= limit

Примеры:

если limit=3 предыдущий список должен стать:

 li_result = [[1,2,3,4], [5,6,7,8,9,10], [11,12,13], [14,15,16]]  
  

если limit=2 предыдущий список должен стать:

 li_result = [[1,2,3,4], [5,6] [7,8,9,10], [11,12], [13,14,15,16]]  
  

если limit=1 предыдущий список должен стать:

 li_result = [[1],[2,3,4],[5,6],[7,8,9,10],[11],[12],[13],[14,15,16]]
  

Для объединения я мог бы использовать из

  itertools import chain
 list(chain.from_iterable(li)
  

Как бы мне ограничить объединение на основе моего limit значения?

Комментарии:

1. that are shorter кажется, вы имеете в виду больше?

2. Вы можете сделать что-то вроде [i for i in li if len(i)>limit]

Ответ №1:

Это может сработать:

 from typing import Any, List

def combine_to_max_size(l: List[List[Any]], limit: int) -> List[List[Any]]:
    origin = l[:]  # Don't change the original l
    result = [[]]
    while origin:
        if len(result[-1]) >= limit:
            result.append([])
        result[-1].extend(origin.pop(0))
    return result
  

Несколько тестов:

 l = [[1],[2, 3],[4, 5, 6]]
assert combine_to_max_size(l, 1) == [[1], [2, 3], [4, 5, 6]]
assert combine_to_max_size(l, 2) == [[1, 2, 3], [4, 5, 6]]
assert combine_to_max_size(l, 4) == [[1, 2, 3, 4, 5, 6]]
assert l == [[1],[2, 3],[4, 5, 6]]
  

Это решение содержит примечания к вводу. Для использования в Python 2.7 замените

 def combine_to_max_size(l: List[List[Any]], limit: int) -> List[List[Any]]:
  

С:

 def combine_to_max_size(l, limit):
    # type: (List[List[Any]], int) -> List[List[Any]]

  

Комментарии:

1. Я получаю SyntaxError: недопустимый синтаксис def combine_to_max_size(l: List[List[Any]], limit: int) -> List[List[Any]]: Возможно, это потому, что я использую python 2.7

2. Добавлен способ заставить это работать в Python 2.7 объяснение.

Ответ №2:

Я бы просто использовал цикл:

 def limited_concat(li, limit):
    if not li:
        return []
    out = [[]]
    for sublist in li:
        if len(out[-1]) < limit:
            out[-1].extend(sublist)
        else:
            out.append(sublist[:])
    return out


li = [[1],[2,3,4],[5,6],[7,8,9,10],[11],[12],[13],[14,15,16]]
limited_concat(li, 2)
# [[1, 2, 3, 4], [5, 6], [7, 8, 9, 10], [11, 12], [13, 14, 15, 16]]
  

Ответ №3:

Вы можете использовать функцию accumulate() :

 def func(l, limit): 
    acc = list(accumulate(l, lambda x, y: x   y if len(x) < limit else y))
    res = list(filter(lambda x: len(x) >= limit, acc))
    if len(acc[-1]) < limit:
        res.append(acc[-1])
    return res
  

Тест:

 l = [[1],[2,3,4],[5,6],[7,8,9,10],[11],[12],[13],[14,15,16]]
print(func(l, 3))
# [[1, 2, 3, 4], [5, 6, 7, 8, 9, 10], [11, 12, 13], [14, 15, 16]]

print(func(l, 2))
# [[1, 2, 3, 4], [5, 6], [7, 8, 9, 10], [11, 12], [13, 14, 15, 16]]

print(func(l, 1))
# [[1], [2, 3, 4], [5, 6], [7, 8, 9, 10], [11], [12], [13], [14, 15, 16]]

l = [[1,2,3],[4]]
print(func(l, 3))
# [[1, 2, 3], [4]]

l = [[1],[2]]
print(func(l, 3))
# [[1, 2]]
  

Комментарии:

1. Мне нравится идея, но она завершится неудачей с l = [[1,2,3],[4]] и limit=3 , поскольку не сможет вернуть последний [4] . Он также вернет [[]] for l = [[1,2]] с тем же ограничением.

2. @ThierryLathuille Спасибо за подсказку. Это была проблема с последним подсписком. Я отредактировал свое решение.

3. Добро пожаловать! 🙂 Однако по-прежнему происходит сбой с l = [[1],[2]] , он возвращает [[2]]