Victoree's Blog

[2] 데이터 구조체 - 시퀀스, 튜플, 정렬 본문

Python/Fluent Python

[2] 데이터 구조체 - 시퀀스, 튜플, 정렬

victoree 2023. 6. 15. 12:52
728x90

시퀀스

지능형 리스트와 제너레이터 표현식은 시퀀스를 생성하고 초기화하는 강력한 표기법이다. 튜플은 익명 필드를 가진 레코드 및 불변 리스트로 사용할 수 있다. 튜플을 레코드로 사용할 때는 튜플 언패킹이 필드에 접근하는 가장 안전하고 가독성 좋은 방법이다. 
sort()와 sorted() 내장 함수는 사용하기 쉬우며, 선택적인 key 인수에 정렬을 계산하는 함수를 지정할 수 있으므로 융통성도 뛰어나다. 정렬된 시퀀스의 순서를 유지하면서 항목을 추가하려면, bisect.insort() 메소드를 사용하고, 정렬된 시퀀스를 효율적으로 검색하려면 bisect.bisect() 메소드를 사용하자. 

1.1 지능형 리스트와 제너레이터 표현식

시퀀스를 읽어서 개수를 세거나 어떤 항목을 골라내거나 합계를 구하는 등 for 루프는 다양한 일에 사용하는데, 지능형 리스트는 오로지 새로운 리스트를 만드는 일만 한다. 

tshirts = [(color, size) for size in sizes for color in colors]

제너레이터 표현식은 반복자 프로토콜을 이용해서 항목을 하나씩 생성하여 메모리를 더 적게 사용한다. 제너레이터 표현식이 함수에 보내는단 하나의 인수라면, 괄호안에 또 괄호를 넣을 필요는 없다. 배열 생성자는 인수를 두 개 받기때문에, 표현식 앞뒤에 반드시 괄호를 넣어야 한다. 배열 생성자의 첫 인수는 배열의 들어갈 숫자들을 저장할 자료형을 지정한다. 

for tshirt in ('%s %s' % (c, s) for c in colors for s in sizes):

 

1.2 튜플

from collections import namedtuple
City = namedtuple('City', 'name country population')
tokyo = City('Tokyo', 'JP', 36.993)

 

튜플은 다른 자료형을 내부에 담는 경우가 종종 있는데, 튜플의 각 항목은 실제로 하나의 필드이며 각 필드의 타입은 독립적이기 때문에 이는 자연스러운 현상이다. 

튜플 내에 가변형 리스트가 있을 때? 아래 코드는 튜플에는 item assignment가 일어날 수 없다는 에러를 발생하지만, t를 출력해보면 해당 연산이 수행되어있다. 

t = (1, 2, [30, 40])
t[2] += [50, 60] -> raise Error : tuple object는 Item assignment를 지원하지 않음
t
(1,2,[30, 40, 50, 60])

불변형 시퀀스인 튜플에 가변 항목을 넣는 것은 좋은 생각이 아니다. 또한 복합 할당은 원자적 연산이 아니다. 

1.3 리스트의 리스트 만들기

>>> two_dimensions = [['']*3 for i in range(3)]
[['', '', ''], ['', '', ''], ['', '', '']]

1.4 정렬

sort() 메소드는 객체의 상태를 변경하고 새로운 리스트를 생성하지 않았음을 알려주기 위해 None을 반환한다. 반면 sorted() 함수는 새로운 리스트를 생성해서 반환한다. 

bisect(haystack, needle) 은 정렬된 시퀀스인 haystack 안에서 오름차순 정렬상태를 유지한 채로 needle을 추가할 (들어갈) 위치를 찾아낸다. 이 함수의 결과값을 인덱스로 사용해서 haystack.insert(index, needle) 을 호출하면 이를 추가할 수 있는데, 이 함수보다 insort() 함수가 이 과정을 더 빨리 처리한다. 

728x90
Comments