2017-02-08 4 views
0

Почему эти два фрагмента кода дают разные результаты? Я предполагаю, что понимание списка создает новый список, а не изменяет его назначенную переменную.Учет списка не работает при динамическом изменении списка

import numpy as np 
x = np.array([1, 1, 1, 1]) 
x = [2 + x[0:i] .dot(y[0:i]) for i in range(0, len(x))] 

print(x) # returns [2, 3, 5, 8] 

x = np.array([1, 1, 1, 1]) 
for i in range(0, len(x)): 
    x[i] = 2 + x[0:i] .dot(y[0:i]) 
print(x) # returns [2, 4, 12, 48] 
+3

Да, список осмыслений создает новый список. Почему вы ожидаете, что это будет разрушительно? Обратите внимание, что возвращенный список будет обычным списком python, а не массивом numpy. –

+0

Назначение переменной * никогда не изменяет объект *. Кажется, у вас уже есть ответ ... Я не понимаю, почему вы задали вопрос ... –

ответ

0

ваших первых строк построить список понимание (временный переменный), а затем изменить й после того, как все вычисления сделано.

Ваша версия на основе циклов выполняет вычисления, меняет x [0], а затем возвращается для выполнения следующего вычисления. x теперь изменен, поэтому вход в вычисление отличается от того, что вы имели в первом примере.

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

x = np.array([1, 1, 1, 1]) 
result = [0, 0, 0, 0] 
for i in range(0, len(x)): 
    result[i] = 2 + x[0:i] .dot(y[0:i]) 
    print (x, result) 
+0

Есть ли способ изменить список «на лету», используя общее понимание списка? – aminsadeghi

+0

Если вы имеете в виду, можете ли вы делать частичные обновления, как это делает ваш цикл, нет. Это не то, как работает понимание списка. Понимание создает новый объект в соответствии с данными инструкциями. Обновление или назначение не являются частью документированной цели. Оператор присваивания * заканчивает * оценивает правую сторону, прежде чем он назначит переменную слева. – Prune

0

Во второй попытке, вы используете этот x[0:i], тот же самый Numpy массив, который вы назначая через каждую итерацию. Вот почему он получает другой результат.

попробовать что-то вроде этого,

x = np.array([1, 1, 1, 1]) 
x_ = x[:] 
for i in range(0, len(x)): 
    x[i] = 2 + x_[0:i] .dot(y[0:i]) 

Список постижение создаст новый массив,