2017-02-08 9 views
0

なぜこれら2つのコードスニペットが異なる結果を生成するのですか?リストの理解は、割り当てられた変数を変更するのではなく、新しいリストを作成すると仮定します。第二の試みにおいてリストを動的に変更するとリストの理解が機能しない

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

はい、リスト内包表記によって新しいリストが作成されます。なぜあなたはそれが破壊的であると思いますか?返されるリストは、numpy配列ではなく通常のpythonリストになります。 –

+0

変数への代入*は決してオブジェクト*を変更しません。あなたはまだ答えがあるようです...あなたがなぜ質問を投稿したのか分かりません... –

答えて

0

あなたの最初の行はリスト内包(一時変数)を構築し、その後、計算のすべての後のxを変更しますされます。

ループベースのバージョンでは計算が行われ、x [0]が変更され、次の計算が実行されます。 xが変更されたため、計算への入力は最初の例の入力とは異なります。

これを別の方法で試してください。違いがわかります。 print(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]) 

リスト内包表記は新しい配列を作成し、

関連する問題