Si necesitamos una lista que contenga solo números, entonces el método de matriz es más eficiente que el método de lista. Y las matrices también admiten todas las operaciones relacionadas con secuencias de variables, como eliminar un elemento de una lista (.pop), insertar un elemento (.insert) y agregar varios valores de otra secuencia al final de la lista (.extend ). Además, las matrices también definen métodos más eficientes para leer archivos (.frombytes) y escribir (.tofile).
La creación de una matriz requiere un código de tipo, como matriz ('d'). Este código de tipo se utiliza para representar el tipo de datos del lenguaje C implementado en la parte inferior. Generalmente, la capa inferior de Python que usamos está escrita e implementada en lenguaje C, por lo que también se llama CPython.
Python define los siguientes códigos de tipo:
Código de tipo | Tipo C | Tipo de Python | Bytes ocupados | Comentario |
---|---|---|---|---|
'segundo' | char firmado | En t | 1 | |
'SEGUNDO' | char sin firmar | En t | 1 | |
'u' | Py_UNICODE | Caracteres Unicode | 2 | (1) |
'h' | firmado corto | En t | 2 | |
'H' | corto sin firmar | En t | 2 | |
'yo' | firmado int | En t | 2 | |
'YO' | int sin firmar | En t | 2 | |
'l' | firmado largo | En t | 4 | |
'L' | largo sin firmar | En t | 4 | |
'q' | firmado mucho tiempo | En t | 8 | |
'Q' | sin firmar mucho tiempo | En t | 8 | |
'F' | flotador | flotador | 4 | |
're' | doble | flotador | 8 |
Nota (1): El 'u'
código de tipo corresponde al carácter unicode obsoleto ( Py_UNICODE
es decir wchar_t
) en Python . Dependiendo de la plataforma del sistema, puede ser de 16 o 32 bits.
Por ejemplo, el código de tipo b representa un carácter con signo. La matriz creada por matriz ('b') solo puede almacenar un entero del tamaño de un byte, entre -128 y 127. Con esta restricción, incluso si la secuencia es muy larga y tiene muchos números, puede ahorrar espacio.
Si la matriz tiene un tipo definido, no puede almacenar datos de tipos indefinidos.
Luciano Ramalho dio un ejemplo para ilustrar la eficiencia de las matrices. Primero cree una matriz de 10 millones de números aleatorios de punto flotante, luego escriba los datos y finalmente lea los datos.
from array import array
from random import random
floats = array('d', (random() for i in range(10 ** 7)))
logging.info('floats[-1] -> %s', floats[-1])
fp = open('floats.bin', 'wb')
floats.tofile(fp)
fp.close()
floats2 = array('d')
fp = open('floats.bin', 'rb')
floats2.fromfile(fp, 10 ** 7)
fp.close()
logging.info('floats2[-1] -> %s', floats2[-1])
logging.info('floats2==floats -> %s', floats2 == floats)
resultado de la operación:
INFO - floats[-1] -> 0.9160358679542017
INFO - floats2[-1] -> 0.9160358679542017
INFO - floats2==floats -> True
Analice el rendimiento del código a través del módulo cProfile y obtenga los siguientes resultados:
INFO - 192 function calls (180 primitive calls) in 0.098 seconds
Ordered by: cumulative time
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.061 0.061 0.061 0.061 {method 'fromfile' of 'array.array' objects}
1 0.030 0.030 0.030 0.030 {method 'tofile' of 'array.array' objects}
2 0.007 0.003 0.007 0.003 {built-in method io.open}
...
Se puede ver que solo se necesitan alrededor de 0.01 s para crear una matriz de 10 millones de números de punto flotante aleatorios e implementar operaciones de lectura y escritura de archivos. El tamaño del archivo generado es de aproximadamente 73M.
- Primero use la expresión del generador para crear un objeto iterable para
**
representar la potencia, y luego genere una matriz de punto flotante de doble precisión (el código de tipo es'd '); - El valor de índice -1 de la matriz se puede obtener hasta el último elemento de la matriz;
- "Wb" es abrir el archivo en modo de escritura binaria, w es la abreviatura de escritura y b es la abreviatura de binario;
binario / ˈbaɪnəri
usando solo 0 y 1 como sistema de números
- Al crear una matriz, puede inicializar o crear una matriz vacía sin inicializar, como: matriz ('d');
- El segundo parámetro de entrada del método fromfile () se usa para especificar el rango máximo de valores;
- Puede ver que la matriz leída del archivo es exactamente la misma que la matriz almacenada.
Debido a que array.tofile escribe datos en un archivo binario, es mucho más rápido que escribir directamente en un archivo de texto. Según las estadísticas, la diferencia de rendimiento entre los dos será de casi 7 veces.