web-dev-qa-db-ja.com

Python:変数はいつ参照によって渡され、値によって渡されますか?

可能性のある複製:
Python:参照によって変数を渡す方法は?

私のコード:

locs = [ [1], [2] ]
for loc in locs:
    loc = []

print locs
# prints => [ [1], [2] ]

なぜloclocsの要素の参照ではないのですか?

Python:明示的にコピーされない限り、すべてが参照として渡されます[これは本当ですか? ]

説明してください.. python決定参照とコピー

更新:

実行する方法 ?

def compute(ob):
   if isinstance(ob,list): return process_list(ob)
   if isinstance(ob,dict): return process_dict(ob)

for loc in locs:
   loc = compute(loc)  # What to change here to make loc a reference of actual locs iteration ?
  • locsには最終処理済み応答が含まれている必要があります!
  • enumerateを使いたくないのですが、それなしでも可能ですか?
30
Yugal Jindle

PythonのすべてがJavaで値によって渡され割り当てられるのと同じように、値によって渡され割り当てられます。Pythonのすべての値は参照です(ポインタ)オブジェクトへ。オブジェクトは値にできません。割り当ては常に値(ポインタ)をコピーします。したがって、このような2つのポインタは同じオブジェクトを指すことができます。

あなたの場合、ループのすべての繰り返しは、リストの要素を変数locに割り当てます。次に、変数locに何か他のものを割り当てます。これらの値はすべてポインターです。ポインターを割り当てています。しかし、いかなるオブジェクトにも影響を与えません。

23
newacct

Effbot(別名Fredrik Lundh)は、Pythonの変数受け渡しスタイルをオブジェクトごとの呼び出しとして説明しています: http://effbot.org/zone/call-by-object.htm

オブジェクトはヒープ上に割り当てられ、それらへのポインターはどこにでも渡すことができます。

  • _x = 1000_などの割り当てを行うと、現在のネームスペースの文字列「x」を1000を含む整数オブジェクトへのポインターにマップする辞書エントリが作成されます。
  • _x = 2000_で「x」を更新すると、新しい整数オブジェクトが作成され、新しいオブジェクトを指すように辞書が更新されます。古い1000オブジェクトは変更されていません(オブジェクトが他のものを参照しているかどうかによって、生きている場合と生きていない場合があります)。
  • _y = x_などの新しい割り当てを行うと、「x」のエントリと同じオブジェクトを指す新しい辞書エントリ「y」が作成されます。
  • 文字列や整数のようなオブジェクトはimmutableです。これは、オブジェクトの作成後にオブジェクトを変更できるメソッドがないことを意味します。たとえば、1000個の整数オブジェクトが作成されると、変更されることはありません。数学は、新しい整数オブジェクトを作成することによって行われます。
  • リストのようなオブジェクトはmutableです。これは、オブジェクトを指すものによってオブジェクトの内容を変更できることを意味します。たとえば、x = []; y = x; x.append(10); print yは_[10]_を出力します。空のリストが作成されました。 「x」と「y」の両方が同じリストを指します。 appendメソッドは、リストオブジェクトを変更(更新)し(データベースへのレコードの追加など)、結果は "x"と "yの両方に表示されます。 "(データベースの更新がそのデータベースへのすべての接続から見えるように)。

問題が明らかになることを願っています。

52

Pythonでは、参照または値の観点で考えることは役に立ちません。どちらも正しくありません。

Pythonでは、変数は単なる名前です。 forループでは、locはリスト内の現在の要素を指す単なる名前です。 loc = []単に再バインド名前locを別のリストに追加し、元のバージョンをそのままにします。

しかし、あなたの例では、各要素はリストなので、実際にはmutateその要素であり、それは元のリストに反映されます:

for loc in locs:
    loc[0] = loc[0] * 2
8
Daniel Roseman

あなたが言う時

loc = []

loc変数を新しく作成された空のリストに再バインドしています

おそらくあなたが欲しい

loc[:] = []

Locのスライス(たまたまリスト全体)を空のリストに割り当てます

5
John La Rooy

すべてはオブジェクトによって渡されます。再バインドと変更は異なる操作です。

locs = [ [1], [2] ]
for loc in locs:
    del loc[:]

print locs

Locがlocsの要素の参照ではないのはなぜですか?

それは。または、少なくとも、Pythonの他のすべての変数と同じ意味です。 Python変数はストレージではなく名前です。 loc[[1,2], [3,4]]の要素を参照するために使用される名前であり、locsは構造全体を参照する名前です。

loc = []

これは意味しない "locが名前を付けているものを見て、それを[]に変換する"それは、できないという意味です。なぜなら、Pythonオブジェクトは不可能のようなものだからです。

代わりに、「locが現在名前になっているものの名​​前であるのをやめ、代わりに[]の名前になり始める」ことを意味します。 (もちろん、それはそこに提供されている特定の[]を意味します。一般に、メモリ内には同じオブジェクトがいくつか存在する可能性があるためです。)

当然、locsの内容は結果として変更されません。

2
Karl Knechtel