프로그래밍/Python

[Fluent Python] 2장 - 데이터 구조체 정리

Dibrary 2022. 4. 15. 09:50
반응형

안녕하세요 Dibrary입니다.

'전문가를 위한 파이썬' 2장 정리 내용 입니다.

 

컨테이너 시퀀스 = list, tuple, collections, deque
균일 시퀀스 = str, bytes, bytearray, memoryview, array.array

컨테이너 시퀀스는 객체의 참조를 담고 있습니다.

균일 시퀀스는 을 직접 담고 있습니다. 값과 참조의 차이를 코드로 살펴보겠습니다.

list를 예로 들면, alpha값이 변하니까 alpha를 가지고 있던 tmp의 값도 변하네요. (참조하고 있었기 때문이죠)

 

원래 튜플은 불변형인데, 이렇게 하면 변경이 됩니다. (즉, 이렇게 사용하면 안 됩니다.)
튜플도 컨테이너 시퀀스라서 참조를 담고 있기 때문에 변경이 되네요.

 

반면 str은 아래처럼 작성시 그저 값이 써집니다. 즉, 원본이 바뀌어도 b는 변화 없는걸 보실 수 있습니다.

 


다음으로 지능형 리스트라고 내용이 나오는데, 그냥 '리스트 컴프리헨션'이라는 말을 더 많이 쓰는 것 같습니다.

반복문으로 리스트 안에 데이터를 담을 때 한 번에 해결하는 방법입니다. 

코드를 보시면, 굳이 for문을 따로 쓴 것 보다 코드가 간단하고, 생성된 내용은 같습니다.

 

데이터에서 map, filter를 사용할것 없이 그냥 '리스트 컴프리헨션' 사용하면 더 편리합니다.

보시면 for문을 도는 x값이 조건문으로 먼저 가서 2로 나뉘는 값만 리스트에 담겨집니다.
즉, 한 번에 필터링 된 값을 구할 수 있습니다.

 

두 개의 데이터를 혼합시킬 수도 있습니다.

이를 책에서는 '데카르트 곱'이라고 표현했습니다. 말 그대로 모든 경우인 셈입니다.
코드 예시의 경우, 3*2 = 6으로 6개의 데이터가 나옵니다.

 

위 '리스트 컴프리헨션'에서 대괄호를 그냥 괄호로 바꿔주면 제너레이터가 됩니다.

(경우에 따라 데이터가 많을 경우 리스트보다 제너레이터를 쓰면 메모리 사용량을 효과적으로 바꿀 수 있습니다.)

 


튜플과 리스트는 언패킹이 가능합니다. (파이썬 코딩의 기술 way 6에도 나옴)

함수에 전달인자로 넣을 때도 언패킹이 가능합니다.

잘 보시면 함수에 값을 전달할 때 * 를 붙여준 것을 보실 수 있습니다. *를 안 쓰고 변수를 넣으면 에러를 보실 수 있습니다.

 

for문으로 순회할 때도 언패킹이 가능합니다. 

 

명명된 튜플은 튜플에 이름을 지어주는 기능입니다.

함수에서 반환 변수가 여러개라고 할 때 이렇게 namedtuple을 사용해서 한개의 객체로 넘겨준 후에 사용하는 방법도 있습니다. (VO객체 처럼)

 


슬라이싱은 index로 값을 잘라서 가져오는 혹은 변경할 수 있는 기능입니다.

위 코드는 해당 인덱스 범위에 값을 바꾸거나 가져와봤습니다.

인덱스를 가져올 때 2번째 숫자의 index는 포함하지 않는다는 것을 주의하셔야 합니다.

숫자를 3개도 쓸 수 있습니다.
3번째 슬라이싱 숫자는 건너뛰는 간격을 의미하는데 사용하지 않는 것을 추천합니다. (파이썬 코딩의 기술 way 12 참고)

 

리스트안에 리스트를 내포한 변수를 만들 때 주의해야 할 점이 있습니다. (알고리즘에서 많이 만들곤 하죠)

리스트 컴프리헨션으로 만든 리스트의 리스트는 한 개의 값만 변경할 때 한 개만 변경됩니다.
그러나 단순히 곱셈으로 만든 리스트의 리스트는 모양은 같더라도, 한 개의 값만 변경할 때 같은 위치가 모두 변경됩니다.

이는, *를 사용했을 때 하나의 리스트를 * 한 만큼의 갯수가 참조하고 있었기 때문입니다.

 


마지막으로 메모리뷰 기능이 있습니다.
bytes를 복사하지 않고 배열의 슬라이스를 다룰 수 있게 해 줍니다.

중간에 memoryview를 사용해서 변경한 것을 잘 보시면 됩니다. memv로 변경된 값은 기존 길이 *2가 되었죠?

그러면 2개씩이 하나의 기존 값인데 8개 비트로 구성한 것입니다.

위 코드를 보면 254, 255는 -2입니다.    1, 0은 1입니다. (왼쪽부터 비트를 보면 됩니다)

index를 이용해서 0, 0을 0, 4로 변경한 후에 원래 값을 보면 0에서 1024로 변경되었죠?

즉, 첫 번째 0은 8비트가 모두 0이고, 2번째는 4니까 왼쪽에서 3번째 비트가 1인 셈입니다. 
그러면 2의 10제곱이 되고 이는 1024가 됩니다.

728x90
반응형