Le fractionnement d'une liste en N parties de longueur à peu près égale
Quelle est la meilleure façon de diviser la liste en environ parties égales? Par exemple, si la liste contient 7 éléments et est divisé en 2 parties, nous voulons obtenir 3 éléments dans une partie, et l'autre doit avoir 4 éléments.
Je suis à la recherche de quelque chose comme even_split(L, n)
qui rompt L
en n
pièces.
def chunks(L, n):
""" Yield successive n-sized chunks from L.
"""
for i in xrange(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ération en cours et prendre le premier élément de chaque colonne, appel que la première partie, puis prendre la deuxième et de la mettre dans la partie deux, etc), mais qui détruit l'ordre des éléments.
InformationsquelleAutor | 2010-01-25
Vous devez vous connecter pour publier un commentaire.
Voici un qui pourrait travailler:
Test:
>>> chunkIt(range(8), 6)
=>[[0], [1], [2, 3], [4], [5], [6], [7]]
chunkIt(range(10), 9)
doit retourner 9 pièces, mais il ne le fait pas.if num > len(seq): num = len(seq)
au début de la fonction.Vous pouvez l'écrire assez simplement comme un générateur de liste:
Exemple:
n = min(n, len(a)) # don't create empty buckets
sur la ligne 1, pour éviter la création de vider les seaux dans de tels scénarioslist(split(range(X, Y)))
oùX < Y
range
au lieu dexrange
œuvres en python 3.Aussi longtemps que vous ne voulez pas quelque chose de stupide comme continue morceaux:
zip(*chunkify(range(13), 3))
résultats dans[(0, 1, 2), (3, 4, 5), (6, 7, 8), (9, 10, 11)]
itertools.zip_longest
à la fin avec un supplément de tuple avec la 12 dans ilmap(None, *chunkify(range(13), 3))
qui donne[(0, 1, 2), (3, 4, 5), (6, 7, 8), (9, 10, 11), (12, None, None)]
C'est le raison d'être pour
numpy.array_split
*:*crédit à Zéro Pirée dans la chambre 6
*
dansprint
pour?Modifiant le code de rendement
n
morceaux plutôt que de morceaux den
:qui donne:
Cela va affecter les éléments supplémentaires pour le dernier groupe, qui n'est pas parfait, mais bien à l'intérieur de votre cahier des charges de "l'à peu près N parties égales" 🙂 Par cela, je veux dire 56 éléments serait mieux comme (19,19,18) considérant que cela donne (18,18,20).
Vous pouvez obtenir plus équilibrée de la sortie avec le code suivant:
sorties:
for x in chunks(mylist,num): print x
, j'ai souhaité morceaux, mais entre eux-je obtenir une liste vide. Aucune idée pourquoi? C'est, je reçois beaucoup de[]
, après chaque morceau.n > len(l)
, a ajouté un cas particulier pour que,if len(l) < n: return [[x] for x in l]
Si vous divisez
n
éléments dans à peu prèsk
morceaux vous pouvez fairen % k
morceaux 1 élément plus grand que les autres morceaux de distribuer les éléments supplémentaires.Le code suivant va vous donner la longueur pour les morceaux:
Exemple:
n=11, k=3
résultats dans[4, 4, 3]
Vous pouvez facilement calculer le début indizes pour les morceaux:
Exemple:
n=11, k=3
résultats dans[0, 4, 8]
À l'aide de la
i+1
th morceau comme de la frontière, nous obtenons que l'i
ème partie de la listel
avec lenn
estComme une étape finale de créer une liste de tous les segments à l'aide de la liste de compréhension:
Exemple:
n=11, k=3, l=range(n)
résultats dans[range(0, 4), range(4, 8), range(8, 11)]
Ici est celui qui ajoute
None
pour faire les listes de même longueurVoir
more_itertools.diviser
:Installer via
> pip install more_itertools
.Ont un coup d'oeil à numpy.split:
La mise en œuvre utilisation de numpy.linspace méthode.
Il suffit de spécifier le nombre de pièces que vous voulez que la matrice soit divisé en deux.Les divisions seront de taille équivalente.
Exemple :
Donne :
Voici ma solution:
Produit
Voici un générateur qui peut gérer n'importe quel positive (entier) nombre de morceaux. Si le nombre de morceaux est plus grand que la liste d'entrées longueur de certains morceaux seront vides. Cet algorithme alterne entre le court et le long des morceaux plutôt qu'en les séparant.
J'ai aussi inclus un code pour tester le
ragged_chunks
fonction.Nous pouvons faire de cette légèrement plus efficace par l'exportation de la multiplication dans le
range
appel, mais je pense que la version précédente n'est plus lisible (et sèche-linge).Cela va faire la scission en une seule expression:
La liste dans cet exemple, la taille de 18 ans et est divisé en 5 parties. La taille des pièces diffère pas de plus d'un élément.
dire que vous souhaitez diviser en 5 parties:
L'aide de la liste de compréhension:
Ma solution, facile à comprendre
Et le plus court-liner sur cette page(écrit par ma fille)
Une autre façon serait quelque chose comme ceci, l'idée ici est d'utiliser le mérou, mais de se débarrasser de
None
. Dans ce cas, nous aurons tous "small_parts" formé à partir d'éléments lors de la première partie de la liste, et "larger_parts' de la fin de la liste. Longueur de "grandes parties" est len(small_parts) + 1. Nous avons besoin de considérer x comme deux sous-parties.La façon dont je l'ai mis en place renvoie une liste de tuples:
Voici une autre variante qui se propage le "reste" des éléments de manière uniforme entre tous les morceaux, un à la fois jusqu'à ce qu'il n'en reste aucune. Dans cette mise en œuvre, le plus gros morceaux se produire au début du processus.
Par exemple, de générer de 4 morceaux à partir d'une liste de 14 éléments:
Le même que job réponse, mais prend en compte les listes de taille plus petite que le nombre de formes de packets.
si n (nombre de morceaux) est de 7, et lst (la liste de fracture) est [1, 2, 3] les morceaux sont [[0], [1], [2]] au lieu de [[0], [1], [2], [], [], [], []]
Vous pouvez également utiliser:
Cueillis dans ce lien, et c'est ce qui m'a aidé. J'ai eu une liste pré-définie.
J'ai écrit le code dans ce cas moi-même:
divide_ports(1, 10, 9) serait de retour
L'arrondi de l'linspace et en l'utilisant comme un index est une solution plus facile que ce que amit12690 propose.