39

forPython でループを使用してリスト内の項目を反復処理する場合、 item(以下) を変更すると、対応する項目が変更されitemsますか?

for item in items:
    item += 1

アイテム内の各アイテムはインクリメントされますか、それともループ前と同じままですか?

[注: Python 2.7 と 3.x に興味があります]

4

2 に答える 2

30

いいえ、Pythonの変数はポインターではありません。

代わりにヒープ上のオブジェクトを参照し、変数に割り当てると、参照されるオブジェクトは変更されませんが、変数は変更されます。変数とオブジェクトは、バルーンに関連付けられたラベルのようなものです。割り当ては、代わりにラベルを別のバルーンに関連付けます。

バルーンとラベルのアイデアをもう少し詳しく調べるには、この以前の私の回答を参照してください。

とはいえ、一部のオブジェクトタイプは、特定のインプレース加算動作を実装します。オブジェクトが変更可能である場合(バルーン自体が変更される可能性があります)、インプレース追加は割り当てではなく変更として解釈される可能性があります。

したがって、整数の場合、整数は不変であるためitem += 1、実際にはと同じです。新しい整数オブジェクトを作成し、ラベルをその新しいオブジェクトに関連付ける必要がありitem = item + 1ます。item

一方、リスト変更可能であり、lst += [other, items]として実装され、バルーン自体lst.__iadd__([other, items])を変更します。lst割り当ては引き続き行われますが、メソッドが新しいオブジェクトではなく単に返すため、同じオブジェクトの再割り当てです。ラベルを同じバルーンに再結合することになります。.__iadd__()self

ループは、各反復でリスト内の次の項目への参照を提供するだけです。元のリスト自体を変更することはできません(これはバルーンラベルの別のセットです)。代わりに、含まれている各アイテムに新しいラベルを付けます。

于 2013-02-11T15:06:57.413 に答える
12

まあ、それは本当にアイテムに依存します。

次の場合を考えてみましょう。

class test():
    pass

a = test()
a.value = 1

b = test()
b.value = 2

l = [a,b]

for item in l:
    item.value += 1

for item in l:
    print item.value

>>> 
2
3

この場合:

l2 = [1,2,3]

for item in l2:
    item += 1

for item in l2:
    print item

>>> 
1
2
3

ご覧のとおり、 Martijnが言ったようにポインタを理解する必要があります。

于 2013-02-11T15:07:05.000 に答える