#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.72. Добавлен способ заставить это работать в 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]
. Он также вернет[[]]
forl = [[1,2]]
с тем же ограничением.2. @ThierryLathuille Спасибо за подсказку. Это была проблема с последним подсписком. Я отредактировал свое решение.
3. Добро пожаловать! 🙂 Однако по-прежнему происходит сбой с
l = [[1],[2]]
, он возвращает[[2]]
…