Добавление к списку пустого массива - странные события - PullRequest
0 голосов
/ 18 декабря 2018

Использование Python3.5.3 в Spyder 3.1.3 на Raspbian на Raspberry Pi.Добавление двух numpy-массивов к списку с именем list0 хорошо работает с выделенными numy-массивами 'a', например:

import numpy as np

list0 = []
a = np.array([[1,2,3],[2,3,4]])
list0.append(a)
a = np.array([[11,12,13],[12,13,14]])
list0.append(a)

print("list0 =",list0)

работает хорошо, давая в качестве вывода (немного лучше отформатированный для поста):

list0 = [ array([[ 1,  2,  3], [ 2,  3,  4]]), 
          array([[11, 12, 13], [12, 13, 14]]) ]

Заменив присвоение на использование цикла, происходят странные вещи:

import numpy as np
a = np.empty((3), int)
list0 = []
for idx in range(4):    
    for i in range(3):
        a[i] = idx*10 + i
    print("idx =",idx,"; a =",a)
    list0.append(a)
print("list0 =",list0)

Вторая строка сообщает Python форму используемого массива (в моем первоначальном случае это триразмерный массив).Для проверки сгенерированные массивы с именем 'a' распечатываются.При добавлении вновь заполненных массивов 'a' к 'list0' наконец-то в четыре раза отображается последняя строка.

idx = 0 ; a = [ 0  1  2]
idx = 1 ; a = [10 11 12]
idx = 2 ; a = [20 21 22]
idx = 3 ; a = [30 31 32]
list0 = [ array([30, 31, 32]), array([30, 31, 32]), 
          array([30, 31, 32]), array([30, 31, 32]) ] 

Я полагаю, что list0 просто содержит для раз указатель на массив 'a', который существует тольков одном экземпляре / диапазоне памяти.

Итак: Как я могу физически добавить (скопировать?) каждый из различных массивов 'a' в список?Это ошибка Python или это просто мое недопонимание чего-то?Конечно, я должен думать более питонским; в)

Спасибо за помощь, Питер

1 Ответ

0 голосов
/ 18 декабря 2018

Проблема

Вы добавляете тот же массив a к вашему list0 4 раза.Массивы, подобные a, являются изменяемыми объектами, что означает, среди прочего, что при назначении им значений изменяется базовый объект.Поскольку массив присутствует в вашем списке 4 раза, эти изменения (кажется) появляются в 4 разных местах.

Решение

Вы можете исправить свой код с одним небольшим изменением.Добавьте копию массива в ваш список вместо самого массива:

import numpy as np
a = np.empty((3), int)
list0 = []
for idx in range(4):    
    for i in range(3):
        a[i] = idx*10 + i
    print("idx =",idx,"; a =",a)
    list0.append(a.copy())
print("list0 =",list0)

Вывод:

idx = 0 ; a = [0 1 2]
idx = 1 ; a = [10 11 12]
idx = 2 ; a = [20 21 22]
idx = 3 ; a = [30 31 32]
list0 = [array([0, 1, 2]), array([10, 11, 12]), array([20, 21, 22]), array([30, 31, 32])]

Оптимизированное решение

Python / Numpy предлагают намного лучшеспособы (как с точки зрения использования меньшего количества строк кода, так и более быстрого выполнения) для инициализации массивов.Для ряда диапазонов, подобных этому, здесь разумный подход:

list0 = [np.arange(n*10, n*10+3) for n in range(4)]
print(list0)

Вывод:

[array([0, 1, 2]), array([10, 11, 12]), array([20, 21, 22]), array([30, 31, 32])]

Можно также рассмотреть возможность использования одного 2D-массива вместо списка массивов.,С одним отдельным массивом часто проще работать, чем с неоднородной комбинацией массивов в списке.Вот как это сделать:

arr0 = np.array([np.arange(n*10, n*10+3) for n in range(4)])
print(arr0)

Вывод:

[[ 0  1  2]
 [10 11 12]
 [20 21 22]
 [30 31 32]]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...