Đó là một chút thông minh.
Đầu tiên, như đã lưu ý trong một nhận xét, trong Python 3 zip()
trả về một trình lặp, vì vậy bạn cần bao gồm toàn bộ nội dung list()
để lấy lại danh sách thực tế, vì vậy kể từ năm 2020, nó thực sự:
list(zip(*original[::-1]))
Đây là sự cố:
[::-1]
- tạo một bản sao ngắn của danh sách gốc theo thứ tự ngược lại. Cũng có thể sử dụng reversed()
mà sẽ tạo ra một trình lặp ngược trên danh sách thay vì thực sự sao chép danh sách (hiệu quả hơn về bộ nhớ).
*
- làm cho mỗi danh sách con trong danh sách ban đầu trở thành một đối số riêng biệt để zip()
(tức là giải nén danh sách)
zip()
- lấy một mục từ mỗi đối số và tạo một danh sách (tốt, một bộ) từ các đối số đó và lặp lại cho đến khi tất cả các danh sách con hết. Đây là nơi mà sự chuyển vị thực sự xảy ra.
list()
chuyển đổi kết quả đầu ra của zip()
một danh sách.
Vì vậy, giả sử bạn có điều này:
[ [1, 2, 3],
[4, 5, 6],
[7, 8, 9] ]
Đầu tiên bạn nhận được điều này (bản sao nông, đảo ngược):
[ [7, 8, 9],
[4, 5, 6],
[1, 2, 3] ]
Tiếp theo, mỗi danh sách con được chuyển làm đối số cho zip
:
zip([7, 8, 9], [4, 5, 6], [1, 2, 3])
zip()
liên tục sử dụng một mục từ đầu mỗi đối số của nó và tạo một bộ từ đó, cho đến khi không còn mục nào nữa, dẫn đến (sau khi nó được chuyển đổi thành danh sách):
[(7, 4, 1),
(8, 5, 2),
(9, 6, 3)]
Và Bob là chú của bạn.
Để trả lời câu hỏi của @ IkeMiguel trong một nhận xét về việc xoay nó theo hướng khác, khá đơn giản: bạn chỉ cần đảo ngược cả trình tự đi vào zip
và kết quả. Điều đầu tiên có thể đạt được bằng cách loại bỏ [::-1]
và thứ hai có thể đạt được bằng cách ném reversed()
xung quanh toàn bộ. Vì reversed()
trả về một trình vòng lặp trên danh sách, chúng tôi sẽ cần đặt list()
xung quanh đó để chuyển đổi nó. Với một vài list()
lệnh gọi bổ sung để chuyển đổi các trình vòng lặp thành một danh sách thực tế. Vì thế:
rotated = list(reversed(list(zip(*original))))
Chúng ta có thể đơn giản hóa điều đó một chút bằng cách sử dụng lát cắt "Mặt cười của sao Hỏa" thay vì reversed()
... thì chúng ta không cần lớp vỏ ngoài list()
:
rotated = list(zip(*original))[::-1]
Tất nhiên, bạn cũng có thể chỉ cần xoay danh sách theo chiều kim đồng hồ ba lần. :-)