J'ai une liste contenant des éléments de sous-listes qui ressemblent à ceci:
itertools import chain list(chain.from_iterable(li)
Je voudrais concaténer toutes les sous-listes qui sont plus courtes qu'une certaine valeur limite avec les sous-listes suivantes jusqu'à ce que la longueur de la nouvelle sous-liste soit> = limit
Exemples:
si limit = 3 le précédent la liste doit devenir:
li_result = [[1],[2,3,4],[5,6],[7,8,9,10],[11],[12],[13],[14,15,16]]
si limit = 2 la liste précédente doit devenir:
li_result = [[1,2,3,4], [5,6] [7,8,9,10], [11,12], [13,14,15,16]]
si limit = 1 la liste précédente devait devenir:
li_result = [[1,2,3,4], [5,6,7,8,9,10], [11,12,13], [14,15,16]]
Pour concaténer je pourrais utiliser de
li = [[1],[2,3,4],[5,6],[7,8,9,10],[11],[12],[13],[14,15,16]]
3 Réponses :
Celui-ci pourrait fonctionner:
def combine_to_max_size(l, limit):
# type: (List[List[Any]], int) -> List[List[Any]]
Quelques tests:
def combine_to_max_size(l: List[List[Any]], limit: int) -> List[List[Any]]:
Cette solution contient des annotations de frappe. Pour utiliser dans Python 2.7, remplacez
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]]
Par:
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
J'obtiens SyntaxError: syntaxe invalide def combine_to_max_size (l: List [List [Any]], limit: int) -> List [List [Any]]: Je pourrais l'être parce que j'utilise python 2.7
Ajout d'un moyen de le faire fonctionner sous Python 2.7 + explication.
J'irais simplement avec une boucle:
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]]
Vous pouvez utiliser la fonction accumulate():
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]]
Test:
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
J'aime l'idée, mais elle échouera avec l = [[1,2,3], [4]] et limit = 3 , car elle ne renvoie pas le dernier [4] . Il renverrait également [[]] pour l = [[1,2]] avec la même limite.
@ThierryLathuille Merci pour l'indication. C'était le problème avec la dernière sous-liste. J'ai édité ma solution.
Je vous en prie! :) Il échoue toujours avec l = [[1], [2]] , il renvoie [[2]] , cependant ...
qui sont plus courts, il semble que vous voulez dire plus longtemps?Vous pouvez faire comme
[i for i in li if len (i)> limit]