5

私はPythonが初めてです。リストについて私が持っている質問は次のとおりです。リストは可変で、タプルは不変であると言われています。しかし、私が次のように書くとき:

L1 = [1, 2, 3]
L2 = (L1, L1)
L1[1] = 5
print L2

結果は

([1, 5, 3], [1, 5, 3])

それ以外の

([1, 2, 3], [1, 2, 3])

しかしL2、タプルであり、タプルは不変です。の値を変更すると の値L1L2変更されるのはなぜですか?

4

7 に答える 7

7

Pythonのドキュメント(http://docs.python.org/reference/datamodel.html)から、次の点に注意してください。

可変オブジェクトへの参照を含む不変コンテナオブジェクトの値は、後者の値が変更されると変更される可能性があります。ただし、コンテナに含まれるオブジェクトのコレクションは変更できないため、コンテナは引き続き不変と見なされます。したがって、不変性は不変の値を持つことと厳密には同じではなく、より微妙です。

于 2012-09-01T20:33:08.397 に答える
4

タプルは不変ですが、タプル内のリストは変更可能です。タプルではなく、L1(リスト)を変更しました。タプルにはL1のコピーが2つ含まれているため、実際には同じリストであるため、両方とも変更が表示されます。

オブジェクトが「不変」である場合、それは、オブジェクトが触れるすべてのものも不変であることを自動的に意味するわけではありません。変更可能なオブジェクトを不変のオブジェクト内に配置することができます。これにより、変更可能なオブジェクトの変更を続行できます。

于 2012-09-01T20:32:25.973 に答える
4

タプルは変更されませんでしたが、指定したリストと同じ重複参照が含まれています。

タプルではなく(より正確には、タプル内のリストへの参照ではなく)リストL1)を変更しました。

たとえば、あなたはすることができなかっただろう

  L2[1] = 5

タプル正しく述べると不変だからです。

そのため、タプルは変更されませんでしたが、タプルに参照が含まれているリストが変更されました(両方のエントリが同じリストへの参照であったため、出力の両方の値がに変更されました5)。タプルの値は変更されていません。

この文脈で参照を「ポインタ」と考えると役立つ場合があります。

編集(以下のコメントのOPによる質問に基づく):

参考文献、リスト、コピーについては、これらの例が役立つかもしれません。

L=range(5)
s = (L, L[:]) # a reference to the original list and a copy

s
([0, 1, 2, 3, 4], [0, 1, 2, 3, 4])

次にL[2]を変更します

L[2] = 'a'

与える:

s
([0, 1, 'a', 3, 4], [0, 1, 2, 3, 4])  # copy is not changed

「2番目」のリストにはコピーが含まれているため、変更されていないことに注意してください。

今、

L=range(5)

リストの2つのコピーを作成し、タプルへの参照を提供しています

s = (L[:], L[:])

now 
L[2] = 'a'

元のリストL以外には影響しません

s
 ([0, 1, 2, 3, 4], [0, 1, 2, 3, 4])

これがお役に立てば幸いです。

于 2012-09-01T20:32:29.740 に答える
2

タプルは不変です。L2はL1への2つの参照の不変のタプルであり(最初に表示されるように、2つのリストのタプルではありません)、L1は不変ではありません。L1を変更する場合、L2を変更するのではなく、L2が参照するオブジェクトのみを変更します。

于 2012-09-01T20:35:19.393 に答える
2

の代わりにディープコピーを使用し=ます。

from copy import deepcopy
L2 = deepcopy(L1)

于 2012-09-01T20:39:47.247 に答える
1

タプルには2つの参照が含まれており、それぞれが同じリストを参照しています(予想どおり、リストのコピーではありません)。したがって、リストの変更は引き続きタプルに表示されますが(タプルには参照のみが含まれているため)、タプル自体は変更されません。したがって、不変性に違反することはありません。

于 2012-09-01T20:32:50.813 に答える
0

タプルが不変であることは、1つのことだけを意味します。タプルを作成すると、それを変更することはできません。一方、リストは、要素を追加したり、要素を削除したりすることができます。ただし、タプルとリストはどちらも、それらに含まれる要素に関係しますが、それらの要素が何であるかには関係しません。

Pythonでは、これはタプルやリストとは関係ありません。intなどの単純な値を追加すると、そのまま表示されますが、リスト、タプル、その他のクラスタイプのオブジェクトなどの複雑な値は常に参照として保存されます。

タプルをに変換すると、set()驚くかもしれないエラーメッセージが表示されますが、上記のことを考えると、それは理にかなっているはずです。

>>> L=range(5)
>>> s = (L, L[:]) # a reference to the original list and a copy
>>> set(1, 2, s)
>>> set((1, 2, s))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'

の値はset、セットに追加された後は決して変更されてはならないため、不変のタプル内に含まれる可変の値はすべてs上昇しTypeErrorます。

于 2012-09-02T17:22:29.443 に答える