ใน Python ฉันเห็นค่าตัวแปรสองค่าที่สลับกันโดยใช้ไวยากรณ์นี้:
left, right = right, left
สิ่งนี้ถือว่าเป็นวิธีมาตรฐานในการสลับสองค่าตัวแปรหรือมีวิธีอื่นที่ตัวแปรสองตัวที่ใช้โดยทั่วไปมักสลับกันหรือไม่
ใน Python ฉันเห็นค่าตัวแปรสองค่าที่สลับกันโดยใช้ไวยากรณ์นี้:
left, right = right, left
สิ่งนี้ถือว่าเป็นวิธีมาตรฐานในการสลับสองค่าตัวแปรหรือมีวิธีอื่นที่ตัวแปรสองตัวที่ใช้โดยทั่วไปมักสลับกันหรือไม่
คำตอบ:
Python ประเมินค่านิพจน์จากซ้ายไปขวา ขอให้สังเกตว่าในขณะที่การประเมินการมอบหมายด้านขวามือจะถูกประเมินก่อนทางด้านซ้าย
http://docs.python.org/3/reference/expressions.html#evaluation-order
นั่นหมายถึงการแสดงออกดังต่อไปนี้a,b = b,a
:
b,a
จะถูกประเมินนั่นก็คือการสร้าง tuple ของสององค์ประกอบในหน่วยความจำ องค์ประกอบทั้งสองเป็นวัตถุที่กำหนดโดยตัวระบุb
และa
ที่มีอยู่ก่อนที่คำสั่งจะถูกเข้ารหัสในระหว่างการดำเนินการของโปรแกรมa
ถูกกำหนดให้กับองค์ประกอบแรกของ tuple (ซึ่งเป็นวัตถุที่เป็นb อย่างเป็นทางการก่อนการแลกเปลี่ยนเนื่องจากมีชื่อb
) b
ถูกกำหนดให้กับองค์ประกอบที่สองของ tuple (ซึ่งเป็นวัตถุที่เคยเป็นมาก่อนหน้าการแลกเปลี่ยนเพราะตัวระบุเป็นa
)กลไกนี้ได้เปลี่ยนวัตถุที่กำหนดให้กับตัวระบุa
และb
ดังนั้นเพื่อตอบคำถามของคุณ: ใช่เป็นวิธีมาตรฐานในการสลับสองตัวระบุบนวัตถุสองรายการ
โดยวิธีการที่วัตถุไม่ได้เป็นตัวแปรพวกเขาเป็นวัตถุ
a, b, c = c, a, b
เช่น
นั่นเป็นวิธีมาตรฐานในการสลับสองตัวแปรใช่
ฉันรู้จักสามวิธีในการสลับตัวแปร แต่a, b = b, a
วิธีที่ง่ายที่สุดคือ นั่นคือ
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]
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]
: ปัญหาคือเมื่องูหลามทำการมอบหมายด้านซ้ายnums[i]
มีการเปลี่ยนแปลงซึ่งทำให้การnums[nums[i] - 1]
เปลี่ยนแปลงที่ไม่คาดคิด U สามารถคิดในตอนแรกต้องการ u nums[1],nums[2] = nums[2],nums[1]
แต่หลังจากnums[1] = nums[2]
วิ่งคุณไม่ต้องnums[2] = nums[1]
แทน u 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 Array
เพื่อแก้ไขปัญหาที่อธิบายโดย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
คุณสามารถรวมการแลกเปลี่ยนtupleและ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