730 votes

Créer une liste d'éléments uniques répétés N fois

Je veux créer une série de listes, toutes plus ou moins longues. Chaque liste contient le même élément e répétées n temps (où n = longueur de la liste).

Comment créer les listes, sans utiliser un programme de compréhension des listes ? [e for number in xrange(n)] pour chaque liste ?

1079voto

Mark Byers Points 318575

Vous pouvez également écrire :

[e] * n

Vous devez noter que si e est par exemple une liste vide, vous obtenez une liste avec n références à la même liste, et non pas n listes vides indépendantes.

Tests de performance

À première vue, il semble que la répétition est le moyen le plus rapide de créer une liste avec n éléments identiques :

>>> timeit.timeit('itertools.repeat(0, 10)', 'import itertools', number = 1000000)
0.37095273281943264
>>> timeit.timeit('[0] * 10', 'import itertools', number = 1000000)
0.5577236771712819

Mais attendez - ce n'est pas un test équitable...

>>> itertools.repeat(0, 10)
repeat(0, 10)  # Not a list!!!

La fonction itertools.repeat ne crée pas réellement la liste, il crée simplement un objet qui peut être utilisé pour créer une liste si vous le souhaitez ! Essayons à nouveau, mais en convertissant en liste :

>>> timeit.timeit('list(itertools.repeat(0, 10))', 'import itertools', number = 1000000)
1.7508119747063233

Donc si vous voulez une liste, utilisez [e] * n . Si vous voulez générer les éléments paresseusement, utilisez repeat .

37 votes

Il est très peu probable que la performance de la création d'une liste avec des éléments identiques soit une composante critique de la performance d'un programme python.

21 votes

Comme mentionné ci-dessus, si e est une liste vide [[]] * n peut produire des résultats inattendus . Pour créer sous-listes vides uniques , utiliser pour la compréhension : [[] for i in range(0,n)]

203voto

Kekito Points 2470
>>> [5] * 4
[5, 5, 5, 5]

Faites attention lorsque l'élément répété est une liste. La liste ne sera pas clonée : tous les éléments feront référence à la même liste !

>>> x=[5]
>>> y=[x] * 4
>>> y
[[5], [5], [5], [5]]
>>> y[0][0] = 6
>>> y
[[6], [6], [6], [6]]

0 votes

Cela a-t-il un sens ? Créer une liste, puis changer un élément, et toute la liste est modifiée ?

2 votes

@Timo. Oui. La liste extérieure stocke quatre références à la même liste intérieure.

115voto

Aaron Hall Points 7381

Créer une liste d'un seul élément répété n fois en Python

En fonction de votre cas d'utilisation, vous souhaitez utiliser différentes techniques avec une sémantique différente.

Multiplier une liste pour les éléments immuables

Pour les éléments immuables, comme None, bools, ints, floats, strings, tuples ou frozensets, vous pouvez procéder comme suit :

[e] * 4

Notez que ceci n'est généralement utilisé qu'avec des éléments immuables (chaînes, tuples, frozensets, ) dans la liste, car ils pointent tous vers le même élément au même endroit en mémoire. Je l'utilise fréquemment lorsque je dois construire une table avec un schéma de toutes les chaînes de caractères, afin de ne pas avoir à fournir un mappage un à un hautement redondant.

schema = ['string'] * len(columns)

Multiplier la liste où nous voulons que le même élément soit répété

En multipliant une liste, on obtient même éléments, encore et encore. Ce besoin est rare :

[iter(iterable)] * 4

Cette fonction est parfois utilisée pour transformer un itérable en une liste de listes :

>>> iterable = range(12)
>>> a_list = [iter(iterable)] * 4
>>> [[next(l) for l in a_list] for i in range(3)]
[[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11]]

On peut voir que a_list contient le même itérateur de plage quatre fois :

>>> a_list
[<range_iterator object at 0x7fde73a5da20>, <range_iterator object at 0x7fde73a5da20>, <range_iterator object at 0x7fde73a5da20>, <range_iterator object at 0x7fde73a5da20>]

Articles mutables

J'utilise Python depuis longtemps maintenant, et j'ai vu très peu de cas d'utilisation où je ferais ce qui précède avec des objets mutables.

Au lieu de cela, pour obtenir, disons, une liste vide mutable, un ensemble ou un dict, vous devez faire quelque chose comme ceci :

list_of_lists = [[] for _ in columns]

L'underscore est simplement un nom de variable à jeter dans ce contexte.

Si vous avez seulement le numéro, ce serait :

list_of_lists = [[] for _ in range(4)]

El _ n'est pas vraiment spécial, mais le vérificateur de style de votre environnement de codage se plaindra probablement si vous n'avez pas l'intention d'utiliser la variable et que vous utilisez un autre nom.


Mises en garde concernant l'utilisation de la méthode immuable avec des éléments mutables :

Attention à faire cela avec des objets mutables quand vous changez l'un d'entre eux, ils changent tous parce qu'ils sont tous identiques. même objet :

foo = [[]] * 4
foo[0].append('x')

foo revient maintenant :

[['x'], ['x'], ['x'], ['x']]

Mais avec des objets immuables, vous pouvez faire en sorte que cela fonctionne car vous changez la référence, pas l'objet :

>>> l = [0] * 4
>>> l[0] += 1
>>> l
[1, 0, 0, 0]

>>> l = [frozenset()] * 4
>>> l[0] |= set('abc')
>>> l
[frozenset(['a', 'c', 'b']), frozenset([]), frozenset([]), frozenset([])]

Mais encore une fois, les objets mutables ne sont pas bons pour cela, car les opérations in-place modifient l'objet, pas la référence :

l = [set()] * 4
>>> l[0] |= set('abc')    
>>> l
[set(['a', 'c', 'b']), set(['a', 'c', 'b']), set(['a', 'c', 'b']), set(['a', 'c', 'b'])]

30voto

Jochen Ritzel Points 42916

Itertools a une fonction juste pour cela :

import itertools
it = itertools.repeat(e,n)

Bien sûr. itertools vous donne un itérateur au lieu d'une liste. [e] * n vous donne une liste, mais, en fonction de ce que vous ferez de ces séquences, la fonction itertools La variante peut être beaucoup plus efficace.

13voto

Mad Scientist Points 6232
[e] * n

devrait fonctionner

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