85 votes

Autre moyen de scinder une liste en groupes de n

Disons que j'ai une liste de longueur arbitraire, L:

L = list(range(1000))

Quelle est la meilleure façon de diviser la liste en groupes de n? C'est la meilleure structure que j'ai été en mesure de venir avec, et pour quelque raison il n'a pas l'impression que c'est la meilleure façon d'accomplir la tâche:

n = 25
for i in range(0, len(L), n):
    chunk = L[i:i+25]

Est-il intégré à faire ce que je suis absent?

Edit: Début de réponses sommes en train de retravailler ma boucle for dans une listcomp, ce qui n'est pas l'idée, vous êtes essentiellement en train de me donner ma réponse exacte de retour dans une forme différente. Je vais voir si il y a un autre moyen pour accomplir cette tâche, comme un hypothétique .split sur les listes ou quelque chose. Je fais aussi de l'utiliser comme un générateur de code que j'ai écrit hier soir:

def split_list(L, n):
    assert type(L) is list, "L is not a list"
    for i in range(0, len(L), n):
        yield L[i:i+n]

165voto

Nadia Alramli Points 40381

Ici, vous allez:

list_of_groups = zip(*(iter(the_list),) * group_size)

Exemple:

print zip(*(iter(range(10)),) * 3)
[(0, 1, 2), (3, 4, 5), (6, 7, 8)]

Si le nombre d'éléments n'est pas divisible par N, mais que vous voulez inclure, vous pouvez utiliser izip_longest mais il n'est disponible que depuis la version 2.6 de python

izip_longest(*(iter(range(10)),) * 3)

Le résultat est un générateur, donc vous devez le convertir en une liste si vous voulez l'imprimer.

Enfin, si vous n'avez pas la version 2.6 de python et collé avec une version plus ancienne, mais que vous voulez toujours avoir le même résultat, vous pouvez utiliser la carte:

print map(None, *(iter(range(10)),) * 3)
[(0, 1, 2), (3, 4, 5), (6, 7, 8), (9, None, None)]

Je tiens à ajouter un peu de vitesse de comparaison entre les différentes méthodes présentées jusqu'à présent:

python -m timeit -s 'from itertools import izip_longest; L = range(1000)' 'list(izip_longest(*(iter(L),) * 3))'
10000 loops, best of 3: 47.1 usec per loop

python -m timeit -s 'L = range(1000)' 'zip(*(iter(L),) * 3)'
10000 loops, best of 3: 50.1 usec per loop

python -m timeit -s 'L = range(1000)' 'map(None, *(iter(L),) * 3)'
10000 loops, best of 3: 50.7 usec per loop

python -m timeit -s 'L = range(1000)' '[L[i:i+3] for i in range(0, len(L), 3)]'
10000 loops, best of 3: 157 usec per loop

python -m timeit -s 'import itertools; L = range(1000)' '[list(group) for key, group in itertools.groupby(L, lambda k: k//3)]'
1000 loops, best of 3: 1.41 msec per loop

La compréhension de liste et le groupe par des méthodes sont clairement plus lent que zip, izip_longest et carte

84voto

Steg Points 4835

Que diriez-vous:

 >>> n = 2
>>> l = [1,2,3,4,5,6,7,8,9]
>>> [ l[i:i+n] for i in range(0, len(l), n) ]
[[1, 2], [3, 4], [5, 6], [7, 8], [9]]
 

56voto

Stephan202 Points 27707

Une recette Python (Dans Python 2.6, utilisez itertools.izip_longest ):

 def grouper(n, iterable, fillvalue=None):
    "grouper(3, 'ABCDEFG', 'x') --> ABC DEF Gxx"
    args = [iter(iterable)] * n
    return itertools.zip_longest(*args, fillvalue=fillvalue)
 

Exemple d'utilisation:

 >>> list(grouper(3, range(9)))
[(0, 1, 2), (3, 4, 5), (6, 7, 8)]
>>> list(grouper(3, range(10)))
[(0, 1, 2), (3, 4, 5), (6, 7, 8), (9, None, None)]
 

Si vous souhaitez que le dernier groupe soit plus court que les autres au lieu d'être complété avec fillvalue , vous pouvez par exemple changer le code de la manière suivante:

 >>> def mygrouper(n, iterable):
...     args = [iter(iterable)] * n
...     return ([e for e in t if e != None] for t in itertools.zip_longest(*args))
... 
>>> list(mygrouper(3, range(9)))
[[0, 1, 2], [3, 4, 5], [6, 7, 8]]
>>> list(mygrouper(3, range(10)))
[[0, 1, 2], [3, 4, 5], [6, 7, 8], [9]]
 

14voto

u0b34a0f6ae Points 14874

Itertools.groupby est un excellent outil. Voici un moyen de scinder une liste d'entiers simplement en utilisant la division entière:

 >>> for key, group in itertools.groupby(range(10), lambda k: k//3):
...  print key, list(group)
... 
0 [0, 1, 2]
1 [3, 4, 5]
2 [6, 7, 8]
3 [9]
 

(La liste doit commencer par 0 pour commencer par un groupe complet.)

11voto

kender Points 18446
 n = 25    
list_of_lists = [L[i:i+n] for i in range(0, len(L), n)]
 

il vous donne la liste des listes [[0..24], [25..49], ..]

Si len(L) % n n'est pas 0, la longueur du dernier élément ( list_of_lists[-1] ) sera len (L)% n.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X