Pythonでは、次の構文を使用して2つの変数値が交換されるのを見ました。
left, right = right, left
これは2つの変数値を交換する標準的な方法と考えられていますか、それとも2つの変数が慣例的に最も普通に交換される他の方法がありますか?
Pythonでは、次の構文を使用して2つの変数値が交換されるのを見ました。
left, right = right, left
これは2つの変数値を交換する標準的な方法と考えられていますか、それとも2つの変数が慣例的に最も普通に交換される他の方法がありますか?
回答:
Pythonは式を左から右に評価します。割り当てを評価する際、右側が左側より先に評価されることに注意してください。
http://docs.python.org/3/reference/expressions.html#evaluation-order
これは、式の次のことを意味しますa,b = b,a
。
b,a
が評価されます。つまり、2つの要素のタプルがメモリに作成されます。2つの要素は、プログラムの実行中に命令が検出される前に存在していた、識別子b
とa
で指定されたオブジェクトです。a
たタプルの最初の要素に割り当てられる(formelyたオブジェクトであるbは、それが名前を持っていたため、スワップ前b
)b
は、タプルの2番目の要素に割り当てられます(これは、識別子がだったため、以前はスワップ前にあったオブジェクトですa
)このメカニズムは効果的識別子に割り当てられたオブジェクトをスワップしているa
と、b
したがって、あなたの質問に答えるには:はい、これは2つのオブジェクトで2つの識別子を交換する標準的な方法です。
ちなみに、オブジェクトは変数ではなく、オブジェクトです。
a, b, c = c, a, b
。
これは、2つの変数を交換する標準的な方法です。
私a, b = b, a
は変数を交換する3つの方法を知っていますが、最も簡単です。有る
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
code
x = x + yy = xy x = xycode
予期しないエラーが発生するため、スワップの標準的な方法であるとは言えません。
nums[i], nums[nums[i] - 1] = nums[nums[i] - 1], nums[i]
nums[i]
最初に変更され、次に2番目の変数に影響しますnums[nums[i] - 1]
。
var c=a
、a=b
、b=c
。そして、最後の割り当てでは、新しい値を使用してa
bのアドレスを評価します。
nums[nums[i] - 1], nums[i] = nums[i], nums[nums[i] - 1]
。問題を解決します。
nums[i], nums[nums[i] - 1] = nums[nums[i] - 1], nums[i]
:問題は、Pythonが左側の代入を行うときnums[i]
に変更され、nums[nums[i] - 1]
予期しない変更が発生することです。あなたは最初にあなたnums[1],nums[2] = nums[2],nums[1]
が望むことを想像することができ nums[1] = nums[2]
ますが、実行後、あなたはもう持っていませんnums[2] = nums[1]
、代わりにあなたは得ましたnums[888] = nums[1]
。
ここでは参照が使用されるため、多次元配列では機能しません。
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配列のスライスの交換も参照してください
eyquemで説明されている問題を回避するには、copy
モジュールを使用して、関数を介して、値の(逆の)コピーを含むタプルを返すことができます。
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
。
タプルとXORスワップを組み合わせることができます:x、y = x ^ x ^ y、x ^ y ^ y
x, y = 10, 20
print('Before swapping: x = %s, y = %s '%(x,y))
x, y = x ^ x ^ y, x ^ y ^ y
print('After swapping: x = %s, y = %s '%(x,y))
または
x, y = 10, 20
print('Before swapping: x = %s, y = %s '%(x,y))
print('After swapping: x = %s, y = %s '%(x ^ x ^ y, x ^ y ^ y))
ラムダを使用する:
x, y = 10, 20
print('Before swapping: x = %s, y = %s' % (x, y))
swapper = lambda x, y : ((x ^ x ^ y), (x ^ y ^ y))
print('After swapping: x = %s, y = %s ' % swapper(x, y))
出力:
Before swapping: x = 10 , y = 20
After swapping: x = 20 , y = 10