Question

Je sais une compréhension de la liste fera, mais je me demandais s'il y a une même approche plus courte (et plus Pythonic?).

Je veux créer une série de listes, tous plus ou moins longues. Chaque liste contient le même élément e, répété n fois (où n = longueur de la liste). Comment puis-je créer les listes, sans faire

[e for number in xrange(n)]

pour chaque liste?

Était-ce utile?

La solution

Vous pouvez également écrire:

[e] * n

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

Les tests de performance

À première vue semble qui se répètent est le meilleur moyen 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 juste ...

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

La itertools.repeat fonction ne crée pas la liste, il crée simplement un objet qui peut être utilisé pour créer une liste si vous le souhaitez! L'essai Let que de nouveau, mais la conversion à une 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, l'utilisation repeat.

Autres conseils

>>> [5] * 4
[5, 5, 5, 5]

Soyez prudent lorsque l'élément se répète une liste. La liste ne sera pas cloné: tous les éléments se référeront à la même liste

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

Créer Liste des seul article n Répété fois en Python

Les produits Immuable

Pour les éléments immuables, comme Aucun, cordes, tuples, ou frozensets, vous pouvez le faire comme ceci:

[e] * 4

Notez que ceci est mieux utilisé avec des éléments immuables (chaînes, tuples, frozensets,) dans la liste, car ils pointent tous vers le même point au même endroit dans la mémoire. J'utiliser souvent quand je dois construire une table avec un schéma de toutes les chaînes, de sorte que je ne dois pas donner une une à une cartographie.

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

objets mutables

Je l'ai utilisé Python depuis longtemps maintenant, et je l'ai jamais vu un cas d'utilisation où je ferais ce qui précède avec une instance mutable. Au lieu de cela, pour obtenir, par exemple, une liste vide mutable, ensemble ou dict, vous devez faire quelque chose comme ceci:

list_of_lists = [[] for _ in columns]

Le trait de soulignement est simplement un nom de variable jetable dans ce contexte.

Si vous avez seulement le nombre, ce serait:

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

Le _ n'est pas vraiment spécial, mais votre style environnement de codage vérificateur se plaindra probablement si vous ne comptez pas utiliser la variable et utiliser un autre nom.


Mise en garde selon la méthode immuable avec des objets mutables:

Méfiez-vous le faire avec des objets mutables , lorsque vous changez l'un d'eux, ils ont tous les changements, car ils sont tous les même objet:

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

foo retourne maintenant:

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

Mais avec des objets immuables, vous pouvez le faire fonctionner parce que vous changez la référence, et non 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, parce que les opérations en place changent 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'])]

itertools a une fonction juste pour que:

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

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

Comme d'autres l'ont souligné, en utilisant l'opérateur * pour un duplicata de l'objet mutables références, donc si vous changez un vous les changer tous. Si vous voulez créer des instances indépendantes d'un objet mutable, votre syntaxe xrange est la façon la plus Pythonic de le faire. Si vous êtes pris la peine en ayant une variable nommée qui est jamais utilisé, vous pouvez utiliser la variable underscore anonyme.

[e for _ in xrange(n)]
[e] * n

devrait fonctionner

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top