ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Python Zip 2차원 배열 회전
    Python/이것저것 파이썬 2020. 10. 24. 16:53
    반응형

    1. zip

    내장 함수(BIF) zip은
    각 iterables의 요소들을 하나씩 모아
    이터레이터를 만듭니다.

    iterable (이터러블)
    멤버들을 한 번에 하나씩 돌려줄 수 있는 객체. 이터러블의 예로는 모든 (list, str, tuple 같은) 시퀀스 형들, dict 같은 몇몇 비 시퀀스 형들, 파일 객체들, __iter__() 나 시퀀스 개념을 구현하는 __getitem__() 메서드를 써서 정의한 모든 클래스의 객체들이 있다.
    a = [1, 2, 3, 4, 5]
    b = ['a', 'b', 'c', 'd', 'e']
    
    for each in zip(a, b):
        print(each)
    (1, 'a')
    (2, 'b')
    (3, 'c')
    (4, 'd')
    (5, 'e')

    튜플로 돌려줍니다.

    파이썬에선 튜플이 기본입니다.
    이런 코드도 튜플로 처리된 겁니다. 

    a, b = 1, 2
    (a, b) = (1, 2)

    2. asterisk(*)

    파이썬의 asterisk는 언패킹(unpacking)에도 사용됩니다. 

    a = [[1, 2, 3, 4, 5], ['a', 'b', 'c', 'd', 'e']]
    
    for each in zip(a[0], a[1]):
        print(each)
    a = [[1, 2, 3, 4, 5], ['a', 'b', 'c', 'd', 'e']]
    
    for each in zip(*a):
        print(each)
    (1, 'a')
    (2, 'b')
    (3, 'c')
    (4, 'd')
    (5, 'e')

    a를 언패킹 할 때 *a 를 쓰니 a[0], a[1] 로 언패킹 되었네요. 
    이렇게 요소의 개수가 고정되어 있는 경우는 하드 코딩해서 언패킹 할 수 있겠지만.
    고정되어 있지 않은 경우는 *로 언패킹하는 게 많이 편합니다. 

    아래는 함수의 parameter에서 많이 사용되는 테크닉입니다만.. 
    일반적인 바인딩에서도 사용할 수 있습니다. 

    a, *b = [1, 2, 3, 4, 5]
    print(a, b)
    1 [2, 3, 4, 5]
    a, *b, c = [1, 2, 3, 4, 5]
    print(a, b, c)
    1 [2, 3, 4] 5

    3. 2차원 리스트 회전

    a = [[1, 2, 3],
         [4, 5, 6],
         [7, 8, 9],
         [10, 11, 12]]
    b = []
    for each in zip(*a):
        b.append(each)
    print(b)
    [(1, 4, 7, 10), (2, 5, 8, 11), (3, 6, 9, 12)]

    반 시계 방향으로 제대로 돌리기 위해선 

    a = [[1, 2, 3],
         [4, 5, 6],
         [7, 8, 9],
         [10, 11, 12]]
    b = []
    for each in reversed(tuple(zip(*a))):
        b.append(each)
    print(b)
    [(3, 6, 9, 12), (2, 5, 8, 11), (1, 4, 7, 10)]

    zip은 튜플을 돌려주니까.. 리스트로.. 

    a = [[1, 2, 3],
         [4, 5, 6],
         [7, 8, 9],
         [10, 11, 12]]
    b = []
    for each in reversed(tuple(zip(*a))):
        b.append(list(each))
    print(b)
    [[3, 6, 9, 12], [2, 5, 8, 11], [1, 4, 7, 10]]

    리스트 컴프리헨션을 사용하면 한 줄로도 가능합니다. 

    a = [[1, 2, 3],
         [4, 5, 6],
         [7, 8, 9],
         [10, 11, 12]]
    b = [list(each) for each in reversed(tuple(zip(*a)))]
    print(b)
    [[3, 6, 9, 12], [2, 5, 8, 11], [1, 4, 7, 10]]

    요소가 튜플이라도 괜찮다면 이렇게 간단하게 ...

    a = [[1, 2, 3],
         [4, 5, 6],
         [7, 8, 9],
         [10, 11, 12]]
    b = list(reversed(tuple(zip(*a))))
    print(b)
    [(3, 6, 9, 12), (2, 5, 8, 11), (1, 4, 7, 10)]

    함수형 프로그래밍에서 많이 사용되는 함수인 map을 이용해 튜플을 리스트로 처리할 수도 있죠. 

    a = [[1, 2, 3],
         [4, 5, 6],
         [7, 8, 9],
         [10, 11, 12]]
    b = list(map(list, reversed(tuple(zip(*a)))))
    print(b)
    [[3, 6, 9, 12], [2, 5, 8, 11], [1, 4, 7, 10]]

    시계 방향으로도 코딩해보세요..

    a = [[1, 2, 3],
         [4, 5, 6],
         [7, 8, 9],
         [10, 11, 12]]
    b = list(map(list, zip(*reversed([*a]))))
    print(b)
    [[10, 7, 4, 1], [11, 8, 5, 2], [12, 9, 6, 3]]
    반응형
Designed by Tistory.