Quelle est la meilleure façon de diviser une liste en parties à peu près égales? Par exemple, si la liste a 7 éléments et est divisée en 2 parties, nous voulons obtenir 3 éléments dans une partie, et l'autre doit avoir 4 éléments.
Je cherche quelque chose comme even_split(L, n)
ça qui se brise L
en plusieurs n
parties.
def chunks(L, n):
""" Yield successive n-sized chunks from L.
"""
for i in range(0, len(L), n):
yield L[i:i+n]
Le code ci-dessus donne des morceaux de 3, plutôt que 3 morceaux. Je pourrais simplement transposer (itérer sur ceci et prendre le premier élément de chaque colonne, appeler cette première partie, puis prendre la seconde et la mettre dans la deuxième partie, etc.), mais cela détruit l'ordre des éléments.
>>> chunkIt(range(8), 6)
=>[[0], [1], [2, 3], [4], [5], [6], [7]]
chunkIt(range(10), 9)
devrait renvoyer 9 parties, mais ce n'est pas le cas.Vous pouvez l'écrire assez simplement sous forme de générateur de liste:
Exemple:
la source
n = min(n, len(a)) # don't create empty buckets
sur la ligne 1 pour éviter de créer des seaux vides dans des scénarios commelist(split(range(X, Y)))
whereX < Y
C'est la raison d'être de
numpy.array_split
*:* crédit à Zero Piraeus dans la chambre 6
la source
*
dansprint
pour?print(L)
et `print (* L). Voir également stackoverflow.com/a/36908/2184122 ou recherchez "python use of asterisk".Tant que vous ne voulez rien de stupide comme des morceaux continus:
la source
zip(*chunkify(range(13), 3))
résultats[(0, 1, 2), (3, 4, 5), (6, 7, 8), (9, 10, 11)]
Changer le code pour produire des
n
morceaux plutôt que des morceaux den
:qui donne:
Cela attribuera les éléments supplémentaires au groupe final qui n'est pas parfait mais qui correspond bien à votre spécification de "à peu près N parties égales" :-) Par là, je veux dire que 56 éléments seraient mieux comme (19,19,18) alors que cela donne (18, 18, 20).
Vous pouvez obtenir la sortie la plus équilibrée avec le code suivant:
qui sort:
la source
for x in chunks(mylist,num): print x
, j'obtiens les morceaux désirés, mais entre eux j'obtiens une liste vide. Une idée pourquoi? Autrement dit, j'en reçois beaucoup[]
, un après chaque morceau.Si vous divisez des
n
éléments en grosk
morceaux, vous pouvez rendre lesn % k
morceaux d'un élément plus gros que les autres morceaux pour distribuer les éléments supplémentaires.Le code suivant vous donnera la longueur des morceaux:
Exemple:
n=11, k=3
résulte en[4, 4, 3]
Vous pouvez ensuite calculer facilement les indications de départ pour les morceaux:
Exemple:
n=11, k=3
résulte en[0, 4, 8]
En utilisant le
i+1
e morceau comme limite, nous obtenons que lei
e morceau de listel
avec lenn
estEn dernière étape, créez une liste de tous les morceaux en utilisant la compréhension de liste:
Exemple:
n=11, k=3, l=range(n)
résulte en[range(0, 4), range(4, 8), range(8, 11)]
la source
Cela fera la division par une seule expression:
La liste de cet exemple a la taille 18 et est divisée en 5 parties. La taille des pièces ne diffère que dans un seul élément.
la source
Voir
more_itertools.divide
:Installez via
> pip install more_itertools
.la source
En voici un qui ajoute
None
pour rendre les listes de longueur égalela source
Voici ma solution:
Produit
la source
Voici un générateur qui peut gérer n'importe quel nombre positif (entier) de blocs. Si le nombre de morceaux est supérieur à la longueur de la liste d'entrée, certains morceaux seront vides. Cet algorithme alterne entre les morceaux courts et longs plutôt que de les séparer.
J'ai également inclus du code pour tester la
ragged_chunks
fonction.Nous pouvons rendre cela légèrement plus efficace en exportant la multiplication dans l'
range
appel, mais je pense que la version précédente est plus lisible (et DRYer).la source
Jetez un œil à numpy.split :
la source
Implémentation à l'aide de la méthode numpy.linspace.
Spécifiez simplement le nombre de parties dans lesquelles vous voulez que le tableau soit divisé. Les divisions seront de taille presque égale.
Exemple :
Donne:
la source
Ma solution, facile à comprendre
Et le plus court one-liner sur cette page (écrit par ma fille)
la source
Utilisation de la compréhension de liste:
la source
Une autre façon serait quelque chose comme ça, l'idée ici est d'utiliser le mérou, mais de s'en débarrasser
None
. Dans ce cas, nous aurons tous les 'small_parts' formés à partir des éléments de la première partie de la liste, et les 'large_parts' de la dernière partie de la liste. La longueur des «parties plus grandes» est len (small_parts) + 1. Nous devons considérer x comme deux sous-parties différentes.La façon dont je l'ai configuré renvoie une liste de tuples:
la source
Voici une autre variante qui répartit les éléments "restants" uniformément entre tous les morceaux, un à la fois jusqu'à ce qu'il n'en reste plus. Dans cette implémentation, les plus gros morceaux se produisent au début du processus.
Par exemple, générez 4 blocs à partir d'une liste de 14 éléments:
la source
La même chose que de travail de réponse, mais prend en compte les listes de la taille plus petite que le nombre de chuncks.
si n (nombre de morceaux) est 7 et lst (la liste à diviser) est [1, 2, 3] les morceaux sont [[0], [1], [2]] au lieu de [[0], [1 ], [2], [], [], [], []]
la source
Vous pouvez également utiliser:
la source
Exemple:
l = [a for a in range(97)]
devrait être composé de 10 parties, chacune ayant 9 éléments sauf le dernier.Production:
la source
Supposons que vous souhaitiez diviser une liste [1, 2, 3, 4, 5, 6, 7, 8] en 3 listes d'éléments
comme [[1,2,3], [4, 5, 6], [7, 8]] , où si les derniers éléments restants sont inférieurs à 3, ils sont regroupés.
Sortie: [[1,2,3], [4, 5, 6], [7, 8]]
Où la longueur d'une partie est 3. Remplacez 3 par votre propre taille de morceau.
la source
1>
2>
la source
voici ma version (inspirée de Max's)
la source
Arrondir l'espace linspace et l'utiliser comme index est une solution plus simple que ce que propose amit12690.
la source
Choisi à partir de ce lien , et c'est ce qui m'a aidé. J'avais une liste prédéfinie.
la source
disons que vous souhaitez diviser en 5 parties:
la source
J'ai écrit moi-même du code dans ce cas:
divide_ports (1, 10, 9) renverrait
la source
ce code fonctionne pour moi (compatible Python3):
exemple (pour le type bytearray , mais cela fonctionne également pour les listes ):
la source
Celui-ci fournit des morceaux de longueur <= n,> = 0
def
par exemple
la source
J'ai essayé la plupart des solutions, mais elles n'ont pas fonctionné pour mon cas, je crée donc une nouvelle fonction qui fonctionne dans la plupart des cas et pour tout type de tableau:
la source