2016-04-03 10 views
5

私はここで何が起こっているのか理解できません。 range関数への参照の追加は、インデックス3での再帰的リストの作成のようなものです。どの範囲関数がPythonリストに対して機能しますか?

一方
>>> x = range(3) 
[0, 1, 2] 
>>> x.append(x) 
[0, 1, 2, [...]] 
>>> x[3][3][3][3][0] = 5 
[5, 1, 2, [...]] 

、私はこれは試してみてください。

>>> x = range(3) 
[0, 1, 2] 
>>> x.append(range(3)) 
[0, 1, 2, [0, 1, 2]] 

私は簡単に後者の場合の理由を推測することができなく、添付のリストに何をしているかrange関数への参照を追加し理解することができません。

+3

なぜこれがありますPython 2と3の両方にタグ付けされていますか? 'range'は2と3では異なって動作します。 – interjay

+2

リストはPythonで参照渡しされます。つまり、最初のシナリオでは、xの値ではなくxにポインタを追加しています。 xにはxへのポインタが含まれるため、その時点で再帰的に自身を呼び出します。 –

+0

@JacobH: "リストは参照渡し"と言うと、リストは他のオブジェクトとは異なる動作をするようです。 – DSM

答えて

9

python2では、rangelistです。

list S、およびPythonで物事のほとんどはオブジェクトとアイデンティティです。

li = [0,1] 
li[1] = li # [0, [...]] 
       # ^----v 
id(li)  # 2146307756 
id(li[1])  # 2146307756 

あなたは自体内のリストを入れているので、あなたが再帰データ構造を作成しています。

+4

これはPython 2固有のものであることに注意してください範囲はPython 3では全く異なりますが、 – MattDMo

+0

@Karolyは答えに感謝しますが、私は5の値割り当てが機能する理由を理解できません。私が学んだことは、[1 ] [0] = 5なら、インデックス1のリストのリストに5から0のインデックスを割り当てることを意味します。 – Rahul

+0

私の例を意味するならば: 'li [1]'は 'li'なので、' li [0] = 5 '。 –

0

最初はこれが奇妙なので、実際にはこれを使用しないでください。この問題はrange関数に固有の問題ではなく、参考文献と関連しています。 x.append(x)に電話すると、基本的にはx[-1] is xと言います。ですから、x[0]を変更するとき、あなたはまた、x[-1][0]を変更し、x[-1][-1][0]など

これは、特定の範囲されていない、あなたがcopy.copyを使用することができることを確認するために:

from copy import copy 

x = range(1) 
x.append(x) # here x[1] is reference to x itself (same object) 
print(x[0], x[1][0], x[1][1][0]) 
x[0] = 1 
print(x[0], x[1][0], x[1][1][0]) # all values change 

# 

x = range(1) 
x.append(copy(x)) # x[1] is a copy of x at previous state (new object) 
print(x[0], x[1][0]) # cannot call x[1][1][0] -> x[1][1] is an int 
x[0] = 1 
print(x[0], x[1][0]) # only the first value changes 

出力:

(0, 0, 0) 
(1, 1, 1) 
(0, 0) 
(1, 0) 
関連する問題