Tengo problemas para entender cómo funcionan las matrices en python.

Escribí este breve código de demostración:

from numpy import zeros

a = zeros((3), 'd')
b = zeros((2,3), 'd')
for i in range(2):
    for j in range(3):
        a[j] = i*j
    b[i] = a
print "A: " + str(a) + "\n"
print "B: " + str(b)

La salida de esto es:

A: [ 0.  1.  2.]
B: [[ 0.  0.  0.] [ 0.  1.  2.]]

Ésta es mi pregunta. ¿Por qué no es la salida para esto:

A: [ 0.  1.  2.]
B: [[ 0.  1.  2.] [ 0.  1.  2.]]

Porque hice los cambios en el mismo a y la dirección de la matriz no ha cambiado.

0
Christoph M. 16 feb. 2017 a las 15:52

3 respuestas

La mejor respuesta

Parece que estás asumiendo que

b[i] = a

Inserta una referencia a a en b. Ese no es el caso. La asignación a un segmento de matriz copia los datos. Este comportamiento es similar a la asignación de sectores con listas.

¿Quizás la confusión proviene de que es diferente al revés?

a = b[i]

No copia, crea una vista; Esto es diferente al corte de lista.

1
Paul Panzer 16 feb. 2017 a las 13:12

Las matrices no muestran el comportamiento que espera, sin embargo, las listas sí lo harán. Vea el siguiente ejemplo:

import numpy as np

a = np.zeros(3, 'd')
b = np.zeros(3, 'd')
c = np.zeros((2,3), 'd')

c[0] = a
c[1] = b

a[1] = 2
b[0] = 1

print 'Matrix A: {}'.format(a)
print 'Matrix B: {}'.format(b)
print 'Matrix C: {}'.format(c)

a = [0, 0, 0]
b = [0, 0, 0]
c = [a, b]

a[1] = 2
b[0] = 1

print 'List A: {}'.format(a)
print 'List B: {}'.format(b)
print 'List C: {}'.format(c)

Cuando usamos matrices, c[0] copia el valor actual de a, c[1] hace lo mismo para b. Las referencias se pierden, por lo que las modificaciones a a y b no tienen efecto en c. Por lo tanto, imprimimos:

Matrix A: [ 0.  2.  0.]
Matrix B: [ 1.  0.  0.]
Matrix C: [[ 0.  0.  0.]
 [ 0.  0.  0.]]

Sin embargo, para las listas, se retienen las referencias. Por lo tanto, imprimimos:

List A: [0, 2, 0]
List B: [1, 0, 0]
List C: [[0, 2, 0], [1, 0, 0]]
0
asongtoruin 16 feb. 2017 a las 13:18

Es [0. 0. 0.] porque:

Los primeros bucles comienzan con "0", así que para "i" el cero:

A [j] = 0 * j

Todo multiplicado por 0 es cero.

0
Christian Frei 16 feb. 2017 a las 13:04