2012-05-16 97 views
22

En C++, que puede crear una matriz como ...¿Cómo crear una lista de tamaño de arreglo en python?

int* a = new int[10]; 

en Python, sólo sé que puedo declarar una lista, que anexar algunos artículos, o como ..

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

¿Puedo inicializar una lista por un tamaño dado, como C++, y no hacer ninguna tarea?

+2

Has _do_ _not_ _need_ para declarar una lista en Python. Solo inicialízalo cuando quieras _a_lo__utilizarlo. – ronakg

+4

Bien, ¿por qué demonios necesitarías eso? – 0605002

+0

Pyhton no es C++. realmente necesita cambiar su forma de pensar al respecto, no es necesario declarar un tamaño fijo en Python. – WeaselFox

Respuesta

28

(tl; dr:. La respuesta exacta a su pregunta es numpy.empty o numpy.empty_like, pero es probable que no les importa y puede salir con el uso myList = [None]*10000)

métodos simples

Usted puede inicializar su lista para todo el mismo elemento. Si tiene sentido semánticamente usar un valor no numérico (que dará un error más adelante si lo usas, lo cual es bueno) o algo así como 0 (inusual ... puede ser útil si estás escribiendo una matriz dispersa o el ' valor por defecto' debe ser 0 y no estás preocupado por los bichos) depende de usted:

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

(Aquí _ es sólo un nombre de variable, se podría haber utilizado i)

también puede. hazlo así:

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

Probablemente don No es necesario optimizar esto. También puede añadir a la matriz cada vez que se necesita:

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

Comparación de rendimiento de métodos simples

¿Cuál es mejor?

>>> 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) 

Resultados 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 

resultados 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 

Como podemos ver, lo más probable es mejor que hacer el lenguaje [None]*10000 tanto en python2 y python3.Sin embargo, si uno está haciendo algo más complicado que la asignación (como cualquier cosa complicada para generar o procesar cada elemento de la lista), entonces la sobrecarga se convierte en una fracción insignificante del costo. Es decir, tal optimización es prematura de la que preocuparse si hace algo razonable con los elementos de su lista.


memoria sin inicializar

Todos estos son sin embargo ineficaz porque pasan por la memoria, escribiendo algo en el proceso. En C, esto es diferente: una matriz no inicializada se llena con memoria aleatoria de basura (nota al margen: que ha sido reasignada del sistema, y ​​puede ser security risk cuando asigna o no puede bloquear y/o no borra la memoria al cerrar el programa) . Esta es una opción de diseño, diseñada para la aceleración: los creadores del lenguaje C pensaron que era mejor no inicializar automáticamente la memoria, y esa era la elección correcta.

Esto no es una aceleración asintótica (porque es O(N)), pero, por ejemplo, no necesitaría inicializar primero el bloque de memoria completo antes de sobrescribir con las cosas que realmente le interesan. Esto, si fuera posible, es equivalente a algo así como (pseudo-código) x = list(size=10000).

Si quiere algo similar en python, puede usar el paquete de manipulación de matriz numérica/N-dimensional-numpy. Específicamente, numpy.empty o numpy.empty_like

Esa es la verdadera respuesta a su pregunta.

+0

'_' es simplemente un nombre" tonto "para una variable que no es realmente necesaria al iterar un rango. Me gustaría simplemente 'para el rango (10)' podría escribirse a veces. –

+0

'x = [[None]] * 10' es" incorrecto ". Pruebe 'x [0] .append (1)' y vea la magia. –

+0

@ Death-Stalker: sí, creo que eso es lo que realmente estaba tratando de señalar e ilustrar ("trabajar con objetos mutables"). Pero gracias, creo que me has hecho darme cuenta de que mi respuesta está horriblemente redactada. Fijo. – ninjagecko

3

No es realmente la forma de pitón para inicializar listas como esta. De todos modos, puede inicializar una lista como esta:

>>> l = [None] * 4 
>>> l 
[None, None, None, None] 
3

Python no tiene nada incorporado para sustentar esto. ¿Realmente necesita optimizarlo tanto como yo no creo que agregar agregará que mucho overhead.

Sin embargo, puede hacer algo como l = [None] * 1000.

Alternativamente, podría usar un generador.

+0

Bien, no estoy muy familiarizado con la gestión de la memoria de Python, cambiaré de opinión. Gracias ~ – wtm

1
your_list = [None]*size_required 
7

Puede usar esto: [None] * 10. Pero esto no será de "tamaño fijo", puede agregar, eliminar ... Así es como se hacen las listas.

Puede hacer que sea una tupla (tuple([None] * 10)) para corregir su ancho, pero nuevamente, no podrá cambiarlo (no en todos los casos, solo si los elementos almacenados son mutables).

Otra opción, más cercana a sus necesidades, no es una lista, sino una collections.deque con una longitud máxima. Es el tamaño máximo, pero podría ser más pequeño.

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

embargo, sólo tiene que utilizar una lista, y acostumbrarse a la forma "Pythonic" de hacer las cosas.

3

Tenga en cuenta también que cuando se utiliza matrices en C++ que podría haber tenido algo diferentes necesidades, que se resuelven de diferentes maneras en Python:

  1. Es posible que haya necesarios sólo una colección de artículos; Las listas de Python tratan con este uso perfectamente.
  2. Es posible que haya necesitado una matriz adecuada de elementos homogéneos. Las listas de Python son no una buena forma de almacenar matrices.

Python resuelve la necesidad en arrays por NumPy, que, entre otras cosas interesantes, tiene una forma de crear un array de tamaño conocido:

from numpy import * 

l = zeros(10) 
+6

El uso de 'from numpy import *' ocultará las construcciones internas de python 'all',' abs', 'min',' max', 'sum',' any' y 'round' con los numpy equivalentes, que pueden no ser siempre Lo que quieras. –

+2

Sí, tenga cuidado de que el módulo 'numpy' contenga bastantes nombres (que sin embargo son convenientes tener en el espacio de nombres de su módulo cuando está escribiendo código de matriz). Si los posibles conflictos de nombres le causan problemas, use importaciones calificadas. – ulidtko

0
fix_array = numpy.empty(n, dtype = object) 

donde n es el tamaño de su matriz

aunque funciona, puede que no sea la mejor idea, ya que tiene que importar una biblioteca para este fin. ¡Espero que esto ayude!

Cuestiones relacionadas