[python] 자료형
Table of Contents
파이썬3 표준 타입#
숫자#
파이썬은 숫자 정수형으로 int 만 제공한다. 파이썬3 에서는 long 이 없다. bool 은 논리 자료형이지만, 파이썬에서는 내부적으로 1(True), 0(False) 으로 처리되는 int의 서브 클래스이다. 따라서 결과적으로 object > int > bool 구조이다.
>>> True == 1
True
>>> False == 0
True
매핑#
매핑 타입은 키와 자료형으로 구성된 복합 자료형이다. 파이썬에는 유일하게 딕셔너리가 있다.
집합#
파이썬 집합 자료형인 set 는 중복된 값을 갖지 않는 자료형이다.
시퀀스#
시퀀스는 어떤 특정 대상의 순서 있는 나열을 뜻한다. str 는 문자의 순서 있는 나열이며, list 는 다양한 값들을 배열 형태로 순서 있는 나열로 구성한다.
원시 타입#
C 나 Java 는 기본적으로 원시 타입(Primitive Type) 를 제공한다. C는 숫자를 표현하기 위해 short, long, long long, unsigned short, unsigned long, float, double, int , usigned int 등 아주 많은 자료형을 제공한다.
원시 타입은 메모리에 정확하게 타입 크기만큼 공간을 할당하고 그 공간을 오로지 값으로 채워 넣는다.
Java 는 원시 타입도 지원하고(int), 원시 타입에 대응되는 클래스 객채 Object (Integer) 도 제공한다.
int a = 5; // 원시 타입
Integer a = new Integer(5); // 클래스 객체(Object)
원시 타입을 객체로 변환하면 여러 가지 작업을 수행할 수 있다. 문자로 변환, 16진수 변환, shifting 과 같은 비트 조작도 가능하다. 대신 메모리 상에 더 많은 공간을 차지한다. 자바의 int 타입은 32bit 인데 비해, 객체인 Integer 는 128bit 이다.
성능을 우선시 하는 C, Java 와 달리 파이썬은 원시 타입을 지원하지 않는다. 파이썬은 원시 타입의 속도를 포기하고 객체의 다양한 기능과 편의성을 택했다.
객체#
파이썬에는 모든 것이 객체이다. 크게 불변 객체와 가변 객체로 구분할 수 있다.
불변 객체#
파이썬에서 변수를 할당한다는 것은 해당 객체에 대해 참조를 한다는 의미이다.
>>> 10
>>> a = 10
>>> b = a
>>> print(id(10), id(a), id(b))
(4393858752, 4393858752, 4393858752)
10 을 a 에 할당하고, b 에 a 를 할당해도 모두 id 값이 같다. 파이썬은 모든 것이 객체이므로, 메모리 상에 위치한 객체의 주소를 얻어오는 id() 함수를 실행한 결과가 모두 같다.
10이 11로 변해도, 값을 담고 있는 변수는 사실 참조일 뿐이고 실제 값을 갖고 있는 int 와 str 모두 불변 객체이다.
불변 객체는 값이 변하지 않으므로 dict 의 key 나 set 의 값으로 사용할 수 있다. 반면 list 와 같이 가변 객체는 값이 변하므로 dict 의 key 나 set 의 값으로 추가할 수 없다.
가변 객체#
list 는 대표적인 가변 객체로 , 값이 변할 수 있다. 다른 변수가 참조하고 있을 때 그 변수의 값 또한 변경된다.
비교 (is, == )#
is 는 id() 를 비교하는 함수이다. 반면, == 는 값을 비교하는 연산자이다.
>>> a = [1,2,3]
>>> a == a
True
>>> a == list(a)
True
>>> a is a
True
>>> a is list(a)
False #id 값이 달라졌다.
>>> a == copy.deepcopy(a)
True
>>> a is copy.deepcopy(a)
False
# copy.deepcopy() 로 복사한 결과 값은 같지만 id 는 다르다.
자료구조 vs. 자료형#
자료구조
데이터에 효율적으로 접근하고 조작하기 위한 데이터의 조직, 관리, 저장 구조. 원시 자료형을 기반으로 하는 배열, 연결 리스트, 객체 등을 말한다.
자료형
컴파일러 또는 인터프리터에게 프로그래머가 데이터를 어떻게 사용하는지 알려주는 일종의 데이터 속성 (Attribute)
리스트 , 딕셔너리#
리스트#
리스트의 주요 연산 시간 복잡도
연산 | 시간복잡도 | 설명 |
---|---|---|
len(a) | O(1) | 전체 요소의 개수를 리턴 |
a[i] | O(1) | 인덱스 i 의 요소 리턴 |
a[i:j] | O(k) | i부터 j 까지 슬라이스의 길이만큼 k 개 요소 리턴. k 개에 대한 조회가 필요하므로 O(k) 이다. |
elem in a | O(n) | elem 요소가 존재하는지 확인. 처음부터 순차 탐색하므로 n 만큼 시간 소요 |
a.count(elem) | O(n) | elem 요소의 개수 리턴 |
a.index(elem) | O(n) | elem 요소의 인덱스 리턴 |
a.append(elem) | O(1) | 리스트 마지막에 elem 요소 추가 |
a.pop() | O(1) | 리스트 마지막 요소를 추출. |
a.pop(0) | O(n) | 리스트 첫번째 요소 추출. 전체 복사가 필요하므로 O(n) 이다. 큐의 연산을 할 거면 O(1) 에 가능한 deque 사용하자. |
del a[i] | O(n) | 최악의 경우 O(n) |
a.sort() | O(nlogn) | Timsort 를 사용하며, 최선의 경우 O(n) 에도 실행가능하다. |
min(a), max(a) | O(n) | 전체 선형 탐색 해야 한다. |
a.reverse() | O(n) | 리스트 순서를 뒤집는다. |
딕셔너리#
파이썬의 딕셔너리는 내부적으로 Hash Table 로 구현되어 있다.
연산 | 시간복잡도 | 설명 |
---|---|---|
len(a) | O(1) | 전체 요소의 개수를 리턴 |
a[key] | O(1) | 키를 조회하여 값을 리턴 |
a[key] = value | O(1) | 키/값을 삽입 |
key in a | O(1) | 딕셔너리에 키가 존재하는지 확인 |
파이썬 3.7 부터는 내부적으로 인덱스를 이용해 딕셔너리도 입력 순서를 유지하도록 했다. 3.7 아래에는 collections.OrderedDict()
라는 자료형을 제공했다.
딕셔너리 모듈#
defaultdict
객체
존재하지 않는 키를 조회할 경우, 에러 메세지를 출력하는 대신 디폴트 값을 기준으로 해당 키에 대한 딕셔너리 아이템을 생성한다.
>>> a = collections.defaultdict(int)
>>> a['A'] = 5
>>> a['B'] = 4
>>> a
defaultdict(<class 'int'>, {'A':5, 'B':4})
>>> a['C'] += 1
>>> a
defaultdict(<class 'int'>, {'A':5, 'B':4, 'C':1})
C라는 key 는 없지만, 디폴트인 0 을 기준으로 연산해준다.
Counter
객체
아이템에 대한 개수를 계산해 딕셔너리로 리턴한다.
>>> a = [1,2,3,4,5,5,5,6,6]
>>> b = collections.Counter(a)
>>> b
Counter({5: 3, 6: 2, 1: 1, 2: 1, 3: 1, 4: 1})
>>> b.most_common(2)
[(5, 3), (6, 2)]
OrderedDict
객체
OrderedDict 에서는 입력 그대로 순서가 유지된다.
Reference#
- 파이썬 알고리즘 인터뷰