ご存知のとおり、2つのアイテムの値を交換するPythonの方法a
はb
a, b = b, a
そしてそれは次の式と同等である。
b, a = a, b
しかし、今日、コードに取り組んでいるときに、次の 2 つの swap が異なる結果をもたらすことを偶然発見しました。
nums = [1, 2, 4, 3]
i = 2
nums[i], nums[nums[i]-1] = nums[nums[i]-1], nums[i]
print(nums)
# [1, 2, 4, 3]
nums = [1, 2, 4, 3]
i = 2
nums[nums[i]-1], nums[i] = nums[i], nums[nums[i]-1]
print(nums)
# [1, 2, 3, 4]
ここで何が起こっているのでしょうか? Python の swap では、2 つの割り当てが同時に独立して行われると考えていました。
参照Python での多重代入と評価順序この種の割り当ての基本的な意味について。
参照多重代入セマンティクス多重代入の左側の括弧の効果と目的について。
ベストアンサー1
オプションで括弧または角括弧で囲まれたターゲット リストへのオブジェクトの割り当ては、次のように再帰的に定義されます。
...
- それ以外の場合: オブジェクトは、ターゲット リスト内のターゲットと同じ数の項目を持つ反復可能オブジェクトである必要があり、項目は左から右へ、対応するターゲットに割り当てられます。
つまり、あなたの課題は
nums[i], nums[nums[i]-1] = nums[nums[i]-1], nums[i]
は、ほぼ
tmp = nums[nums[i]-1], nums[i]
nums[i] = tmp[0]
nums[nums[i] - 1] = tmp[1]
(もちろん、エラーチェックは改善されています)
一方、他の
nums[nums[i]-1], nums[i] = nums[i], nums[nums[i]-1]
のようなものです
tmp = nums[i], nums[nums[i]-1]
nums[nums[i] - 1] = tmp[0]
nums[i] = tmp[1]
したがって、どちらの場合も右辺が最初に評価されます。しかし、左辺の2つの部分は順番に評価され、評価後すぐに代入が行われます。重要なのは、左辺の2番目の項は最初の代入が行われた後にのみ評価されるということです。すでに完了です。したがって、最初に更新するとnums[i]
、 2 番目nums[nums[i] - 1]
に更新する場合とは異なるインデックスが参照されますnums[i]
。