นั่นเป็นบิตที่ชาญฉลาด
ก่อนอื่นตามที่ระบุไว้ในความคิดเห็นใน Python 3 zip()
จะส่งคืนตัววนซ้ำดังนั้นคุณต้องใส่ข้อมูลทั้งหมดlist()
เพื่อดึงรายการจริงกลับออกมาดังนั้นในปี 2020 จึงเป็นจริง:
list(zip(*original[::-1]))
นี่คือรายละเอียด:
[::-1]
- ทำสำเนารายการต้นฉบับแบบตื้นในลำดับย้อนกลับ นอกจากนี้ยังสามารถใช้reversed()
ซึ่งจะสร้างตัววนซ้ำแบบย้อนกลับในรายการแทนที่จะคัดลอกรายการจริง ๆ (หน่วยความจำมีประสิทธิภาพมากขึ้น)
*
- ทำให้แต่ละรายการย่อยในรายการต้นฉบับเป็นอาร์กิวเมนต์แยกกันzip()
(กล่าวคือคลายรายการ)
zip()
- รับหนึ่งรายการจากแต่ละอาร์กิวเมนต์และสร้างรายการ (เช่นทูเพิล) จากสิ่งเหล่านั้นและทำซ้ำจนกว่ารายการย่อยทั้งหมดจะหมด นี่คือจุดที่การขนย้ายเกิดขึ้นจริง
list()
แปลงผลลัพธ์zip()
เป็นรายการ
สมมติว่าคุณมีสิ่งนี้:
[ [1, 2, 3],
[4, 5, 6],
[7, 8, 9] ]
ก่อนอื่นคุณจะได้รับสิ่งนี้ (สำเนาตื้นกลับด้าน):
[ [7, 8, 9],
[4, 5, 6],
[1, 2, 3] ]
ถัดไปของรายการย่อยแต่ละรายการจะถูกส่งเป็นอาร์กิวเมนต์ไปยังzip
:
zip([7, 8, 9], [4, 5, 6], [1, 2, 3])
zip()
ใช้หนึ่งรายการซ้ำ ๆ จากจุดเริ่มต้นของอาร์กิวเมนต์แต่ละรายการและสร้างทูเปิลจากนั้นจนกว่าจะไม่มีรายการอีกต่อไปส่งผลให้ (หลังจากที่มันถูกแปลงเป็นรายการ):
[(7, 4, 1),
(8, 5, 2),
(9, 6, 3)]
และบ๊อบเป็นลุงของคุณ
ในการตอบคำถามของ @ IkeMiguel ในความคิดเห็นเกี่ยวกับการหมุนไปในทิศทางอื่นมันค่อนข้างตรงไปตรงมา: คุณเพียงแค่ต้องย้อนกลับทั้งลำดับที่เข้าzip
และผลลัพธ์ ครั้งแรกสามารถทำได้โดยการลบ[::-1]
และครั้งที่สองสามารถทำได้โดยการขว้างปาreversed()
สิ่งของทั้งหมด ตั้งแต่reversed()
ส่งกลับ iterator กว่ารายการที่เราจะต้องใส่list()
รอบที่แปลงเป็น ด้วยการlist()
เรียกพิเศษสองสามครั้งเพื่อแปลงตัววนซ้ำเป็นรายการจริง ดังนั้น:
rotated = list(reversed(list(zip(*original))))
เราสามารถทำให้มันง่ายขึ้นเล็กน้อยโดยใช้ชิ้นส่วน "Martian smiley" แทนที่จะเป็นreversed()
... จากนั้นเราไม่ต้องการด้านนอกlist()
:
rotated = list(zip(*original))[::-1]
แน่นอนคุณสามารถหมุนรายการตามเข็มนาฬิกาสามครั้งได้ :-)