파이썬 (2)
## 시퀀스 배열
### 컨테이너 시퀀스
- 서로 다른 자료형의 항목을 담을 수 있는 list, tuple, collections.deque 형
- 객체에 대한 참조를 담으며
### 균일 시퀀스
- 단 하나의 자료형만 담을 수 있는, str, bytes, array.array 형
- 자싱늬 메모리 공간에 값을 직접 담는다.
```
메모리에 올라가는 모든 파이썬 객체에는 메타데이터를 담은 헤더가 있다.
ob_refcnt: 객체 참조수
ob_type: 객체의 자료형에 대한 포인터
ob_fval: C 언어의 double 형 실수값
파이썬 64bit에서 각 필드는 8bite를 차지한다.
```
### 가변시퀀스
- list, bytearray, array, deque
### 불변 시퀀스
- tuple, str, bytes
## 제너레이터 표현식
- 일반적으로 제너레이터 표현식이 메모리를 더 적게 사용한다. 전달할 list를 통째로 만들지 않고 반복자 프로토콜을 이용해 하나씩 생성하기 때문이다.
### 불변 리스트를 뛰어넘는 튜플
- 튜플을 단순히 불변리스트로 생각하면 안된다.
- 레코드 관점에서 튜플 안에서 항목의 위치가 항목의 의미를 나타내므로 튜플을 정렬하면 정보가 파괴된다.
### 불변 리스트 튜플
- 명확성 리스트 길이가 변하지 않는다.
- hash(t) 호출을 통해 내부 값이 바뀌지않을거라고 확정할수있다. 가변항목이 들어있다면 TypeError가 발생한다.
- 성능 똑같은 항목을 담은 list보다 메모리를 적게 소비하므로 인터프리터가 최적화를 수행 할 수 있다.
- 하지만 tuple의 불변성은 포함된 참조만 적용되는거지, 실제 가변객체가 immuatable한건 아니다.
- 튜플 리터럴을 평가할때 컴파일러가 한번의 연산으로 튜플 상수에 대한 바이트 코드를 생성하지만(통짜로 상수처리한다), 리스트 리터럴의 경우, 생성된 바이트 코드는 각 항목을 별도의 상수로 만들어 스택에 각각 만든 후 리스트를 만든다.(조합함)
- t라는 튜플을 tuple(t)로 만들면 참조만 반환하지만, list l을 list(l)하게되면 사본을 만든다.
- tuple은 고정된 길이만큼 메모리가 할당되지만, list는 가변되므로 약간의 공간을 더 할당 받는다.
- tuple은 1 depth(객체정보와 데이터참조가 같이 존재)로 값에 접근하지만 list는 2 depth(객체정보가 포인터로 따로 데이터참조로 존재)로 값에 접근한다.
### 시퀀스에 덧셈과 곱셈
- 언제나 객체를 새로 만들고, 피연산자를 변경하지 않는다.
### 시퀀스 복합할당
- += 연산자를 실제로 처리하는 스페셜메서드는 __iadd__이다(i는 in-place의 의미), 파이썬은 __iadd__가 없다면 __add__를 호출한다.
- 당연히 불변 시퀀스에 경우 해당 연산자를 수행할수없다. (가변의 경우 in-place로 동일한 주소값을 확인하지만, 불변 시퀀스는 새로운 주소값이 반환되는것)
```
파이썬 API관례로 객체를 직접 변경하는 함수나 메서더는 None을 반환해서 객체가 변경되었고 객체가 생성되지 않았음을 호출자에게 알려줘야한다.
list.sort()
random.shuffle()
```
## 배열
- 리스트안에 숫자만 들어 있다면 array.array가 훨씬 더 효율적이다.
## SciPy
- 넘파이 기반 라이브러리로 선형대수학, 수치해석, 통계학 계산 알고리즘을 제공한다.
- 대부분 넘파이와 사이파이 함수들은 C, C++로 구현되며, GIL을 해제하므로 모든 CPU 코어를 사용할 수 있다.
## Deque
- thread-safe 양방향 큐, deque은 최대 길이를 설정해 제한된 항목만 유지하므로, 꽉 찬 후에는 새로운 하옴ㄱ을 추가할때 반대쪽 항목을 버린다.