Comment créer une liste de taille de correctif en python?

En C++, je peux créer un tableau comme...

int* a = new int[10];

En python, je sais juste que je peux déclarer une liste, que d'ajouter des éléments, ou comme..

l = [1,2,3,4]
l = range(10)

Puis-je initialiser une liste par une taille donnée,comme c++, et ne faire aucune affectation?

28
demandé sur jamylak 2012-05-16 14:54:03

7 réponses

(tl; dr: la réponse exacte à votre question Est numpy.empty ou numpy.empty_like, mais vous ne vous en souciez probablement pas et pouvez vous en tirer avec myList = [None]*10000.)

Méthodes Simples

Vous pouvez initialiser votre liste à tout le même élément. S'il sémantiquement judicieux d'utiliser une valeur non numérique (qui donnera une erreur plus tard si vous l'utilisez, ce qui est une bonne chose) ou quelque chose comme 0 (inhabituel? peut-être utile si vous écrivez une matrice clairsemée ou que la valeur 'default' devrait être 0 et que vous n'êtes pas inquiet A propos de bugs) est à vous:

>>> [None for _ in range(10)]
[None, None, None, None, None, None, None, None, None, None]

(ici _ est juste un nom de variable, vous auriez pu utiliser i.)

Vous pouvez aussi le faire comme ceci:

>>> [None]*10
[None, None, None, None, None, None, None, None, None, None]

Vous n'avez probablement pas besoin d'optimiser cela. Vous pouvez également ajouter au tableau chaque fois que vous en avez besoin:

>>> x = []
>>> for i in range(10):
>>>    x.append(i)

Comparaison des Performances des méthodes simples

Quel est le meilleur?

>>> def initAndWrite_test():
...  x = [None]*10000
...  for i in range(10000):
...   x[i] = i
... 
>>> def initAndWrite2_test():
...  x = [None for _ in range(10000)]
...  for i in range(10000):
...   x[i] = i
... 
>>> def appendWrite_test():
...  x = []
...  for i in range(10000):
...   x.append(i)

Résultats en python2. 7:

>>> import timeit
>>> for f in [initAndWrite_test, initAndWrite2_test, appendWrite_test]:
...  print('{} takes {} usec/loop'.format(f.__name__, timeit.timeit(f, number=1000)*1000))
... 
initAndWrite_test takes 714.596033096 usec/loop
initAndWrite2_test takes 981.526136398 usec/loop
appendWrite_test takes 908.597946167 usec/loop

Résultats en Python 3.2:

initAndWrite_test takes 641.3581371307373 usec/loop
initAndWrite2_test takes 1033.6499214172363 usec/loop
appendWrite_test takes 895.9040641784668 usec/loop

Comme nous pouvons le voir, il est probablement mieux faire l'idiome [None]*10000 dans python2 et python3. Cependant, si l'on fait quelque chose de plus compliqué que l'affectation (comme tout ce qui est compliqué à générer ou à traiter chaque élément de la liste), alors la surcharge devient une fraction insignifiante du coût. Autrement dit, une telle optimisation est prématurée à craindre si vous faites quelque chose de raisonnable avec les éléments de votre liste.


Mémoire non initialisée

Ce sont tous cependant inefficaces parce qu'ils passent par la mémoire, écrivant quelque chose dans le processus. En C, c'est différent: un tableau non initialisé est rempli de mémoire garbage aléatoire (sidenote: qui a été réaffecté du système, et peut être un risque de sécurité lorsque vous allouez ou échouez à mlock et / ou échouez à supprimer la mémoire lors de la fermeture du programme). C'est un choix de conception, conçu pour accélérer: les fabricants du langage C pensaient qu'il valait mieux ne pas initialiser automatiquement la mémoire, et c'était le choix correct.

Ce n'est pas une accélération asymptotique (parce que c'est O(N)), mais par exemple, vous n'auriez pas besoin d'initialiser tout votre bloc de mémoire avant d'écraser avec des choses qui vous intéressent réellement. Ceci, si c'était possible, équivaut à quelque chose comme (pseudo-code) x = list(size=10000).

Si vous voulez quelque chose de similaire en python, vous pouvez utiliser le paquet de manipulation numpy numerical matrix/n-dimensional-array. Plus précisément, numpy.empty ou numpy.empty_like

C'est la vraie réponse à votre question.

38
répondu ninjagecko 2017-05-23 12:34:34

Vous pouvez utiliser ceci: [None] * 10. Mais ce ne sera pas "taille fixe" que vous pouvez toujours Ajouter, Supprimer ... C'est la façon dont les listes sont faites.

Vous pouvez en faire un tuple (tuple([None] * 10)) pour fixer sa largeur, mais encore une fois, vous ne pourrez pas le changer (pas dans tous les cas, seulement si les éléments stockés sont mutables).

Une Autre option, plus proche de vos besoins, n'est pas une liste, mais un collections.deque, avec une longueur maximale. C'est la taille maximale, mais elle pourrait être plus petite.

import collections
max_4_items = collections.deque([None] * 4, maxlen=4)

Mais, utilisez simplement une liste, et habituez-vous à la façon "pythonique" de faire les choses.

7
répondu jadkik94 2012-05-16 11:12:06

Ce n'est pas vraiment la façon python d'initialiser des listes comme celle-ci. Quoi qu'il en soit, vous pouvez initialiser une liste comme ceci:

>>> l = [None] * 4
>>> l
[None, None, None, None]
4
répondu BluePeppers 2012-05-16 10:57:25

Python n'a rien intégré pour supporter cela. Avez-vous vraiment besoin d'optimiser autant que je ne pense pas que l'ajout permettra d'ajouter que beaucoup de frais généraux.

Cependant, vous pouvez faire quelque chose comme l = [None] * 1000.

Vous pouvez également utiliser un générateur.

3
répondu Russell Dias 2012-05-16 10:57:38

Notez également que lorsque vous avez utilisé des tableaux en C++, vous avez peut-être eu des besoins quelque peu différents, qui sont résolus de différentes manières en Python:

  1. vous auriez peut-être eu besoin d'une collection d'éléments; les listes Python traitent parfaitement ce cas d'utilisation.
  2. vous auriez peut-être besoin d'un tableau approprié d'éléments homogènes. Python, les listes sont pas un bon moyen de stocker tableaux.

Python résout le besoin dans les tableaux par NumPy, qui, entre autres choses intéressantes, a une façon de créer un matrice de taille connue:

from numpy import *

l = zeros(10)
3
répondu ulidtko 2012-05-16 11:14:11
your_list = [None]*size_required
1
répondu cobie 2012-05-16 11:01:38
fix_array = numpy.empty(n, dtype = object)

, Où n est la taille de votre tableau

Bien que cela fonctionne, ce n'est peut-être pas la meilleure idée car vous devez importer une bibliothèque à cet effet. Espérons que cette aide!

0
répondu Mishaa1 2017-06-29 14:00:06