Initialiser une liste à un nombre connu d'éléments en Python [dupliquer]

cette question a déjà une réponse ici:

  • créer une liste vide en python avec une certaine taille 13 Réponses

en ce moment j'utilise une liste, et je m'attendais à quelque chose comme:

verts = list (1000)

devrais-je utiliser array à la place?

199
demandé sur Tim Cooper 2009-02-06 21:58:53

9 réponses

La première chose qui me vient à l'esprit est:

verts = [None]*1000

Mais avez-vous vraiment besoin de preinitialize?

284
répondu Steve Losh 2009-02-06 19:02:00

pas tout à fait sûr pourquoi tout le monde vous donne un moment difficile pour vouloir faire cela - il ya plusieurs scénarios où vous voudriez une liste initialisée de taille fixe. Et vous avez correctement déduit que les tableaux sont sensés dans ces cas.

import array
verts=array.array('i',(0,)*1000)

pour les non-pythonistas, le terme (0,)*1000 crée un tuple contenant 1000 zéros. La virgule Force python à reconnaître (0) comme un tuple, sinon il serait évalué à 0.

j'ai utilisé un tuple au lieu d'une liste parce qu'ils sont généralement plus bas.

66
répondu FoxyLad 2009-12-03 03:46:47

un moyen évident et probablement pas efficace est

verts = [0 for x in range(1000)]

notez que cela peut être facilement étendu à 2 dimensions. Par exemple, pour obtenir un 10x100 "array" vous pouvez faire

verts = [[0 for x in range(100)] for y in range(10)]
54
répondu e-shy 2011-10-28 22:41:50

vouloir initaliser un tableau de taille fixe est une chose parfaitement acceptable à faire dans n'importe quel langage de programmation; ce n'est pas comme si le programmeur voulait mettre une instruction break dans une boucle while(true). Croyez-moi, surtout si les éléments vont juste être écrasés et pas simplement ajoutés/soustraits, comme c'est le cas de beaucoup d'algorithmes de programmation dynamique, vous ne voulez pas jouer avec des déclarations annexées et vérifier si l'élément n'a pas encore été initialisé à la volée (c'est-à-dire beaucoup de code messieurs).

object = [0 for x in range(1000)]

cela fonctionnera pour ce que le programmeur essaie de réaliser.

29
répondu Miko 2014-07-08 21:50:40

@Steve a déjà donné une bonne réponse à votre question:

verts = [None] * 1000

avertissement: comme @Joachim Wuttke l'a souligné, la liste doit être initialisée avec un élément immuable. [[]] * 1000 ne fonctionne pas comme prévu car vous obtiendrez une liste de 1000 listes identiques (similaire à une liste de 1000 points à la même liste en C). Les objets immuables comme int, str ou tuple feront l'affaire.

Alternatives

redimensionner les listes est lent. Les résultats suivants ne sont pas très surprenants:

>>> N = 10**6

>>> %timeit a = [None] * N
100 loops, best of 3: 7.41 ms per loop

>>> %timeit a = [None for x in xrange(N)]
10 loops, best of 3: 30 ms per loop

>>> %timeit a = [None for x in range(N)]
10 loops, best of 3: 67.7 ms per loop

>>> a = []
>>> %timeit for x in xrange(N): a.append(None)
10 loops, best of 3: 85.6 ms per loop

Mais le redimensionnement n'est pas très lent si vous n'avez pas de très grandes listes. Au lieu d'initialiser la liste avec un seul élément (par exemple None ) et une longueur fixe pour éviter le redimensionnement de la liste, vous devriez envisager d'utiliser des compréhensions de liste et remplir directement la liste avec des valeurs correctes. Par exemple:

>>> %timeit a = [x**2 for x in xrange(N)]
10 loops, best of 3: 109 ms per loop

>>> def fill_list1():
    """Not too bad, but complicated code"""
    a = [None] * N
    for x in xrange(N):
        a[x] = x**2
>>> %timeit fill_list1()
10 loops, best of 3: 126 ms per loop

>>> def fill_list2():
    """This is slow, use only for small lists"""
    a = []
    for x in xrange(N):
        a.append(x**2)
>>> %timeit fill_list2()
10 loops, best of 3: 177 ms per loop

Comparaison de numpy

pour d'énormes ensembles de données numpy ou d'autres bibliothèques optimisées sont beaucoup plus rapides:

from numpy import ndarray, zeros
%timeit empty((N,))
1000000 loops, best of 3: 788 ns per loop

%timeit zeros((N,))
100 loops, best of 3: 3.56 ms per loop
14
répondu lumbric 2015-01-02 23:57:20

Vous pourriez faire ceci:

verts = list(xrange(1000))

qui vous donnerait une liste de 1000 éléments dans la taille et qui se trouve être initialisé avec des valeurs de 0-999. Comme list fait un __len__ d'abord à la taille de la nouvelle liste, il devrait être assez efficace.

2
répondu John Montgomery 2009-02-07 18:51:02

vous devriez envisager d'utiliser un type dict au lieu d'une liste pré-initialisée. Le coût d'une recherche dans un dictionnaire est faible et comparable au coût d'accès à un élément de liste arbitraire.

et en utilisant un mapping vous pouvez écrire:

aDict = {}
aDict[100] = fetchElement()
putElement(fetchElement(), fetchPosition(), aDict)
La fonction

et la fonction putElement peuvent stocker des articles à n'importe quelle position. Et si vous avez besoin de vérifier si votre collection contient un élément à un index donné, il est plus pythonique d'écrire:

if anIndex in aDict:
    print "cool!"

que:

if not myList[anIndex] is None:
    print "cool!"

puisque ce dernier suppose qu'aucun réel élément dans votre collection peut être None . Et si cela arrive - votre code se comporte mal.

et si vous avez désespérément besoin de performances et c'est pourquoi vous essayez de pré-initialiser vos variables, et d'écrire le code le plus rapide possible - changer votre langue. Le code le plus rapide ne peut pas être écrit en Python. Vous devriez essayer C à la place et implémenter des wrappers pour appeler votre code pré-initialisé et pré-compilé à partir de Python.

0
répondu Abgan 2009-02-07 18:20:25

:

 lst = [8 for i in range(9)]

crée une liste, les éléments sont initialisés 8

mais ceci:

lst = [0] * 7

créerait 7 listes qui ont un élément

0
répondu Jutta 2018-08-26 11:15:47

sans en savoir plus sur le domaine de problème, il est difficile de répondre à votre question. Sauf si vous êtes certain que vous devez faire quelque chose de plus, la façon pythonique d'initialiser une liste est:

verts = []

vous voyez vraiment un problème de performance? Si oui, quel est le goulot d'étranglement des performances? Ne pas essayer de résoudre un problème que vous n'avez pas. Il est probable que le coût de performance pour remplir dynamiquement un tableau à 1000 éléments est complètement non pertinent pour le programme que vous essayez vraiment d'écrire.

la classe array est utile si les choses dans votre liste vont toujours être un type primitif de longueur fixe (par exemple char, int, float). Mais, il ne nécessite pas de pré-initialisation.

-3
répondu user26294 2009-02-06 21:05:38