0

次のような関数がある場合

def foo(A):
    tmp=A
    tmp=tmp+1
    *rest of the function*
    return

また

def foo(A):
    global tmp
    tmp=A
    tmp=tmp+1
    *rest of the function*
    return

"A" と "tmp" の両方 "tmp" だけではなく、1 が追加されます。私は何を間違っていますか?どうすれば修正できますか?

4

2 に答える 2

0

Blakeの回答の下にあるnneonneoのコメント(問題の重要な部分を説明しています)が述べているように、元の投稿のコードは実際には彼が述べていることを実行しません。例えば:

def foo(A):
   tmp = A
   tmp = tmp + 1
   return (A, tmp)

foo(3)

を返します。これは(3,4)、A が変更されていないことを意味します。

これが当てはまらないのは、 A が可変型の場合です。可変型には、リスト、辞書、およびそれらの派生型が含まれますが、整数、浮動小数点、およびタプルは可変ではありません。

例えば:

def foo(A):
   tmp = A
   tmp[0] = tmp[0] + 1
   return (A, tmp)

foo([1, 2])

を返します([2, 2], [2, 2])。この場合、A は変更されています。

foo は、リストの場合は A の値を変更しますが、整数の場合は変更しないのは、リストが可変で整数がそうでないためです。A が変更可能な型の場合に tmp に A を割り当てると、変更可能なオブジェクトへの参照が割り当てられ、その要素の 1 つを ( のようにtmp[0] = tmp[0] + 1) 変更しても、新しいオブジェクトは作成されません。

たとえば、リストに対してこのような副作用のような動作を関数に持たせたくない場合、一般的な Python のイディオムは、スライス表記を使用してリストを複製することです。これにより、A のリスト オブジェクトのコピーである tmp に割り当てると、新しいリスト オブジェクトが作成されます。

def foo(A):
   tmp = A[:]
   # this slice makes a new list, a copy of A

   tmp[0] = tmp[0] + 1
   return (A, tmp)

foo([1, 2])

これは を返す([1, 2], [2, 2])ので、A は変更されず、tmp が変更されます。

リストやその他の変更可能なオブジェクトをコピーする方法は他にもありますが、これらは互いに微妙に異なります。 リストを複製またはコピーする方法は? あなたの選択についての素晴らしい説明があります。

于 2013-08-28T00:00:17.873 に答える