프로그램에서 2 차원 배열을 회전 할 필요가 있다고 작성했습니다. 최적의 솔루션을 찾다가이 작업을 수행하는 인상적인 원 라이너를 찾았습니다.
rotated = zip(*original[::-1])
지금 내 프로그램에서 사용하고 있으며 예상대로 작동합니다. 내 문제는 그것이 어떻게 작동하는지 이해하지 못한다는 것입니다.
관련된 다른 기능이 원하는 결과를 얻는 방법을 누군가가 설명해 주시면 감사하겠습니다.
답변
다음 2 차원 목록을 고려하십시오.
original = [[1, 2],
[3, 4]]
단계별로 분석해 보겠습니다.
>>> original[::-1] # elements of original are reversed
[[3, 4], [1, 2]]
이 목록은 unpacking 인수 를 zip()
사용하여 전달 되므로 호출은 다음과 동일하게됩니다.zip
zip([3, 4],
[1, 2])
# ^ ^----column 2
# |-------column 1
# returns [(3, 1), (4, 2)], which is a original rotated clockwise
주석이 무엇을하는지 명확하게 zip
해주길 바라며, 인덱스를 기반으로 반복 가능한 각 입력의 요소를 그룹화하거나, 즉 열을 그룹화합니다.
답변
영리한 부분입니다.
첫째, 주석에서 언급했듯이 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()
목록을 통해 반환 반복자, 우리는 넣어해야합니다 list()
주위에 있음을 변환 할 수 있습니다. list()
반복자를 실제 목록으로 변환 하는 몇 가지 추가 호출이 있습니다. 그래서:
rotated = list(reversed(list(zip(*original))))
“Martian smiley”슬라이스를 사용하여 간단히 단순화 할 수 있습니다 reversed()
. 그러면 외부가 필요하지 않습니다 list()
.
rotated = list(zip(*original))[::-1]
물론 목록을 시계 방향으로 세 번 간단히 회전 할 수도 있습니다. 🙂
답변
여기에는 세 부분이 있습니다.
- original [::-1]은 원래 배열을 반대로합니다. 이 표기법은 Python 목록 슬라이싱입니다. 그러면 [start : end : step]에서 설명하는 원래 목록의 “하위 목록”이 제공됩니다. start는 첫 번째 요소이고 end는 하위 목록에서 사용되는 마지막 요소입니다. 단계는 모든 단계의 요소를 처음부터 끝까지 가져 간다고 말합니다. 생략 된 시작과 끝은 슬라이스가 전체 목록이됨을 의미하고 음수 단계는 요소를 역순으로 가져옴을 의미합니다. 예를 들어 원본이 [x, y, z]이면 결과는 [z, y, x]가됩니다.
- 함수 호출의 인수 목록에서 목록 / 튜플 앞에있을 때 *는 목록 / 튜플을 “확장”하여 각 요소가 목록 / 튜플 자체가 아니라 함수에 대한 별도의 인수가됩니다. 따라서 args = [1,2,3]이면 zip (args)는 zip ([1,2,3])과 같지만 zip (* args)는 zip (1, 2,3).
- zip은 각각 길이가 m 인 n 개의 인수를 취하고 길이가 m 인 목록을 생성하는 함수입니다. 요소는 길이가 n이고 각 원본 목록의 해당 요소를 포함합니다. 예를 들어 zip ([1,2], [a, b], [x, y])은 [[1, a, x], [2, b, y]]입니다. Python 문서 도 참조하세요 .
답변
관찰 일뿐입니다. 입력은 목록 목록이지만 매우 멋진 솔루션의 출력은 rotated = zip (* original [::-1]) 튜플 목록을 반환합니다.
이것은 문제가 될 수도 있고 아닐 수도 있습니다.
그러나 쉽게 수정할 수 있습니다.
original = [[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]
def rotated(array_2d):
list_of_tuples = zip(*array_2d[::-1])
return [list(elem) for elem in list_of_tuples]
# return map(list, list_of_tuples)
print(list(rotated(original)))
# [[7, 4, 1], [8, 5, 2], [9, 6, 3]]
list comp 또는 map은 모두 내부 튜플을 다시 목록으로 변환합니다.
답변
def ruota_orario(matrix):
ruota=list(zip(*reversed(matrix)))
return[list(elemento) for elemento in ruota]
def ruota_antiorario(matrix):
ruota=list(zip(*reversed(matrix)))
return[list(elemento)[::-1] for elemento in ruota][::-1]
답변
나도이 문제가 있었고 주제에 대한 훌륭한 wikipedia 페이지를 찾았습니다 ( “Common rotations”단락에서 :
https://en.wikipedia.org/wiki/Rotation_matrix#Ambiguities
그런 다음 무슨 일이 일어나고 있는지 명확하게 이해하기 위해 다음 코드를 매우 자세하게 작성했습니다.
당신이 게시 한 매우 아름답고 영리한 한 줄짜리 글을 더 많이 파는 것이 유용하다는 것을 알게되기를 바랍니다.
빠르게 테스트하려면 여기에 복사 / 붙여 넣기하십시오.
http://www.codeskulptor.org/
triangle = [[0,0],[5,0],[5,2]]
coordinates_a = triangle[0]
coordinates_b = triangle[1]
coordinates_c = triangle[2]
def rotate90ccw(coordinates):
print "Start coordinates:"
print coordinates
old_x = coordinates[0]
old_y = coordinates[1]
# Here we apply the matrix coming from Wikipedia
# for 90 ccw it looks like:
# 0,-1
# 1,0
# What does this mean?
#
# Basically this is how the calculation of the new_x and new_y is happening:
# new_x = (0)(old_x)+(-1)(old_y)
# new_y = (1)(old_x)+(0)(old_y)
#
# If you check the lonely numbers between parenthesis the Wikipedia matrix's numbers
# finally start making sense.
# All the rest is standard formula, the same behaviour will apply to other rotations, just
# remember to use the other rotation matrix values available on Wiki for 180ccw and 170ccw
new_x = -old_y
new_y = old_x
print "End coordinates:"
print [new_x, new_y]
def rotate180ccw(coordinates):
print "Start coordinates:"
print coordinates
old_x = coordinates[0]
old_y = coordinates[1]
new_x = -old_x
new_y = -old_y
print "End coordinates:"
print [new_x, new_y]
def rotate270ccw(coordinates):
print "Start coordinates:"
print coordinates
old_x = coordinates[0]
old_y = coordinates[1]
new_x = -old_x
new_y = -old_y
print "End coordinates:"
print [new_x, new_y]
print "Let's rotate point A 90 degrees ccw:"
rotate90ccw(coordinates_a)
print "Let's rotate point B 90 degrees ccw:"
rotate90ccw(coordinates_b)
print "Let's rotate point C 90 degrees ccw:"
rotate90ccw(coordinates_c)
print "=== === === === === === === === === "
print "Let's rotate point A 180 degrees ccw:"
rotate180ccw(coordinates_a)
print "Let's rotate point B 180 degrees ccw:"
rotate180ccw(coordinates_b)
print "Let's rotate point C 180 degrees ccw:"
rotate180ccw(coordinates_c)
print "=== === === === === === === === === "
print "Let's rotate point A 270 degrees ccw:"
rotate270ccw(coordinates_a)
print "Let's rotate point B 270 degrees ccw:"
rotate270ccw(coordinates_b)
print "Let's rotate point C 270 degrees ccw:"
rotate270ccw(coordinates_c)
print "=== === === === === === === === === "
답변
시계 반대 방향으로 회전 (표준 열 대 행 피벗) 목록 및 사전으로
rows = [
['A', 'B', 'C', 'D'],
[1,2,3,4],
[1,2,3],
[1,2],
[1],
]
pivot = []
for row in rows:
for column, cell in enumerate(row):
if len(pivot) == column: pivot.append([])
pivot[column].append(cell)
print(rows)
print(pivot)
print(dict([(row[0], row[1:]) for row in pivot]))
생성 :
[['A', 'B', 'C', 'D'], [1, 2, 3, 4], [1, 2, 3], [1, 2], [1]]
[['A', 1, 1, 1, 1], ['B', 2, 2, 2], ['C', 3, 3], ['D', 4]]
{'A': [1, 1, 1, 1], 'B': [2, 2, 2], 'C': [3, 3], 'D': [4]}