En ce moment, j'utilise une liste et je m'attendais à quelque chose comme:
verts = list (1000)
Devrais-je utiliser un tableau à la place?
La première chose qui me vient à l’esprit est la suivante:
verts = [None]*1000
Mais avez-vous vraiment besoin de le préinitialiser?
Vous ne savez pas trop pourquoi tout le monde vous donne du fil à retordre, il existe plusieurs scénarios dans lesquels vous souhaiteriez une liste initialisée de taille fixe. Et vous avez correctement déduit que les tableaux sont sensibles dans ces cas.
import array
verts=array.array('i',(0,)*1000)
Pour les non-pythonistes, le terme (0,)*1000
crée un tuple contenant 1 000 zéros. La virgule oblige python à reconnaître (0)
comme un tuple, sinon il serait évalué à 0.
J'ai utilisé un tuple au lieu d'une liste car ils ont généralement des frais généraux moins élevés.
Un moyen évident et probablement pas efficace est
verts = [0 for x in range(1000)]
Notez que cela peut être étendu à 2 dimensions facilement. Par exemple, pour obtenir un "tableau" 10x100, vous pouvez faire
verts = [[0 for x in range(100)] for y in range(10)]
Vouloir intégrer une matrice de taille fixe est une chose parfaitement acceptable 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, en particulier si les éléments vont juste être écrasés et pas simplement ajoutés/soustraits, comme c'est le cas de nombreux algorithmes de programmation dynamique, vous ne voulez pas déranger les instructions append et vérifier si l'élément n'a pas été encore initialisé à la volée (ça fait beaucoup de gents).
object = [0 for x in range(1000)]
Cela fonctionnera pour ce que le programmeur essaie de réaliser.
@Steve a déjà donné une bonne réponse à votre question:
verts = [None] * 1000
Attention: Comme l'a souligné @ Joachim Wuttke, 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 de la même liste en C). Les objets immuables comme int, str ou Tuple iront bien.
Le redimensionnement des 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 devez envisager d'utiliser la compréhension de liste et de remplir directement la liste avec les 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
Pour des ensembles de données volumineux, 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
Vous pourriez faire ceci:
verts = list(xrange(1000))
Cela vous donnerait une liste de 1000 éléments en taille et qui se trouve être initialisée avec des valeurs de 0 à 999. Comme list
fait un __len__
premier pour dimensionner la nouvelle liste, il devrait être assez efficace.
Cette:
lst = [8 for i in range(9)]
crée une liste, les éléments sont initialisés 8
mais ça:
lst = [0] * 7
créerait 7 listes qui ont un élément
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 lorsque vous utilisez un mappage, vous pouvez écrire:
aDict = {}
aDict[100] = fetchElement()
putElement(fetchElement(), fetchPosition(), aDict)
Et la fonction putElement
peut stocker un élément à n’importe quelle position. Et si vous avez besoin de vérifier si votre collection contient un élément à un index donné, il est préférable d’écrire en Pythonic:
if anIndex in aDict:
print "cool!"
Que:
if not myList[anIndex] is None:
print "cool!"
Puisque ce dernier suppose qu'aucun élément réel de votre collection ne peut être None
. Et si cela se produit, votre code se comporte mal.
Et si vous avez désespérément besoin de performances et que vous tentez de pré-initialiser vos variables et écrivez le code le plus rapide possible, changez de langue. Le code le plus rapide ne peut pas être écrit en Python. Vous devriez plutôt essayer C et implémenter des wrappers pour appeler votre code pré-initialisé et pré-compilé à partir de Python.