파이썬에서 가장 빈번하게 사용하는 자료구조는 리스트, 튜플, 셋, 딕셔너리다. 이 네가지 구조는 모두 데이터의 컬렉션(collection)이다.
파이썬은 리스트를 배열처럼 취급한다. 리스트에서 아이템을 검색할 때 걸리는 시간은 선형적으로 증가하기 때문에, 검색이 가능한 대용량의 데이터를 저장하는 용도로는 실용성이 떨어진다.
투플은 변형이 불가능한 리스트로 한 번 생성되면 변형할 수 없다. 튜플 역시 검색에 걸리는 시간이 선형적으로 증가한다.
리스트나 튜플과 달리 셋에는 순서가 없고, 셋이 담고 있는 아이템은 인덱스가 없다. 셋에는 같은 아이템이 중복으로 저장될 수 없으며, 검색 시간은 준선형적인 O(log(N))으로 증가한다. 회원 명단을 조회하거나 중복 항목을 삭제하는 데 셋을 유용하게 사용할 수 있다(중복된 아이템이 들어 있는 리스트를 셋으로 변환하면 중복된 아이템을 모두 삭제한다).
mList = list(set(myList)) # myList에서 중복된 아이템들을 삭제한다.
리스트 데이터를 셋으로 변환해 더 빠르게 회원 명단을 조회해 보자. 예를 들어 bigList라는 리스트에는 정수 1 부터 1000만까지가 문자열로 변환되어 들어 있다고 하자.
bigList = [str(i) for i in range(10000000)]
"abc" in bigList # 0.2초가 걸린다
bigSet = set(bigList)
"abc" in bigSet #15~30마이크로초가 걸린다. 1만 배나 더 빠르다!
딕셔너리는 키(key)를 값(value)에 매핑한다. 숫자, 불, 문자열, 튜플처럼 해시화 할 수 있는 데이터 타입은 키가 될 수 있고, 같은 딕셔너리에 들어 있다 하더라도 키들은 서로 다른 데이터 타입에 속할 수 있다. 값의 데이터 형식에도 별도의 제약 사항은 없다. 딕셔너리의 검색 시간은 준선형적인 O(log(N))으로 증가한다. 키-값으로 검색해야 할 때 딕셔너리는 매우 유용하다.
튜플(키, 값)이 여러 개 있는 리스트에서 딕셔너리를 만들 수 있다. 그리고 내장된 클래스 생성자(constructor)인 enumerate(seq)를 사용해 seq안의 아이템 순분을 키로 지정한 딕셔너리를 만들 수 있다.
seq = ["alpha", "bravo", "charlie", "delta"]
dict(enumerate(seq))
>>>
{0: 'alpha', 1: 'bravo', 2: 'charlie', 3:'delta'}
딕셔너리를 만드는 또 다른 방법은 키 순서열(kseq)과 값 순서열(vseq)에 클래스 생성자인 zip(kseq, vseq)를 사용하는 것이다.
kseq = "abcd" # 문자열 또한 순서열이다.
vseq = ["alpha", "bravo", "charlie", "delta"]
dict(zip(kseq, vseq))
>>>
{'a': 'alpha', 'c': 'charlie', 'b': 'bravo', 'd': 'delta'}
파이썬에서 enumerate(seq)와 zip(kseq, vseq) 함수는 (자주 쓰는 range() 함수 또한) 리스트 제너레이터(generator)로 사용한다. 리스트 제너레이터는 이터레이터(iterator)인터페이스를 제공하는데, 이는 for 루프를 사용 가능하게 한다. 실제 리스트와 달리 리스트 제너레이터는 요청이 있을 때만 다음 아이템을 생산하는 지연 방식(lazy way)으로 작동한다. 제너레이터는 대용량의 리스트를 소화할 수 있으며, 심지어 '무한한'리스트도 허용한다. list() 함수를 사용해 제너레이터를 리스트로 명시적으로 변환할 수 있다.
댓글 없음:
댓글 쓰기