web-dev-qa-db-ja.com

Pythonで2つの変数を交換する標準化された方法はありますか?

Pythonでは、この構文を使って2つの変数値が入れ替わっているのを見ました。

left, right = right, left

これは、2つの変数値を交換する標準的な方法と考えられますか、それとも他の方法で2つの変数を慣例的に交換する方法はありますか。

286
WilliamKF

Pythonは式を左から右に評価します。代入を評価している間、右側が左側の前に評価されることに注意してください。

http://docs.python.org/3/reference/expressions.html#evaluation-order

これは式a,b = b,aに対して次のことを意味します。

  • 右側のb,aが評価されます。つまり、2つの要素からなるタプルがメモリに作成されます。 2つの要素は、プログラムの実行中に命令が実行される前に存在していた、識別子bおよびaによって指定されたオブジェクトです。
  • このTupleを作成した直後には、このTupleオブジェクトの割り当てはまだ行われていませんが、重要ではありません。Pythonはそれがどこにあるかを内部的に認識しています。
  • 次に、左側が評価されます。つまり、タプルは左側に割り当てられます。
  • 左側は2つの識別子で構成されているため、最初の識別子aをTupleの最初の要素に割り当てるためにTupleを展開します(これは以前はbでした。 )b)という名前のため、スワップの前に)
    そして2番目の識別子bは、Tupleの2番目の要素に割り当てられます(これは、その識別子がaであったため、スワップ前は以前aだったオブジェクトです)。

このメカニズムは、識別子abに割り当てられたオブジェクトを効果的に交換しました。

だから、あなたの質問に答えるために:はい、それは2つのオブジェクト上の2つの識別子を交換するための標準的な方法です。
ところで、オブジェクトは変数ではなく、オブジェクトです。

325
eyquem

それが2つの変数を交換する標準的な方法です、そうです。

103
Martijn Pieters

変数を交換する方法は3つありますが、最も簡単なのはa, b = b, aです。がある

XOR(整数用)

x = x ^ y
y = y ^ x
x = x ^ y

あるいは簡潔に

x ^= y
y ^= x
x ^= y

一時変数

w = x
x = y
y = w
del w

タプルスワップ

x, y = y, x
32
NoOneIsHere

予期しないエラーが発生する可能性があるため、これが標準的な交換方法ではないと思います。

nums[i], nums[nums[i] - 1] = nums[nums[i] - 1], nums[i]

nums[i]は最初に変更されてから2番目の変数nums[nums[i] - 1]に影響を与えます。

16
Yi Huang

ここでは参照が使用されているため、多次元配列には機能しません。

import numpy as np

# swaps
data = np.random.random(2)
print(data)
data[0], data[1] = data[1], data[0]
print(data)

# does not swap
data = np.random.random((2, 2))
print(data)
data[0], data[1] = data[1], data[0]
print(data)

Numpy配列のスライスを交換する もご覧ください。

4
gizzmole

eyquem で説明されている問題を回避するには、copyモジュールを使用して、値のコピーを(逆に)含むTupleを返すことができます。

from copy import copy

def swapper(x, y):
  return (copy(y), copy(x))

lambdaと同じ機能:

swapper = lambda x, y: (copy(y), copy(x))

次に、次のように、それらを希望の名前に割り当てます。

x, y = swapper(y, x)

注:必要な場合は、deepcopyの代わりにcopyをインポート/使用できます。

0
LogicalBranch