이번 편의 목표: 튜플의 묶음과 집합의 중복 제거를 구분합니다.
리스트와 딕셔너리를 배웠으니 무엇이든 둘 중 하나에 담을 수 있을 것 같습니다. 실제로 많은 문제를 해결할 수 있습니다. 하지만 바뀌지 않는 한 쌍의 값이나 중복 없는 분류 목록에는 더 의도가 분명한 자료구조가 있습니다.
튜플은 순서가 있는 묶음이다
pair = ("커피", 4500)
item, amount = pair
print(item)
print(amount)
single = (4500,)
print(type(single))
categories = ["식비", "교통", "식비", "문구"]
unique = set(categories)
print(sorted(unique))
print("식비" in unique)
planned = {"식비", "교통", "통신"}
used = {"식비", "문구"}
print(sorted(planned & used))
print(sorted(used - planned))튜플은 `("커피", 4500)`처럼 만듭니다. `item, amount = pair`는 두 요소를 각각의 이름으로 풀어 받는 언패킹입니다. 두 이름에 세 요소를 받는 등 개수가 맞지 않으면 오류가 납니다.
한 요소짜리 튜플에는 쉼표가 필요합니다. `(4500)`은 괄호로 감싼 정수이고 `(4500,)`이 튜플입니다. 튜플은 요소의 연결을 바꿀 수 없어서 `pair[0] = "차"`는 실패합니다. 다만 튜플 안에 리스트가 들어 있다면 그 리스트의 내부 내용까지 고정되는 것은 아닙니다.
집합은 중복 없는 값의 모임이다
`set(categories)`는 중복된 `식비`를 하나로 합칩니다. 집합은 순서를 보장하는 용도로 사용하지 않습니다. 화면에서 일정한 순서로 보려면 `sorted()`로 정렬한 목록을 출력합니다. 따라서 위 예제도 집합 자체 대신 정렬 결과를 보여 줍니다.
`&`는 교집합, `|`는 합집합, `-`는 차집합입니다. 예제에서 예정과 실제에 공통으로 들어 있는 분류는 `식비`이고, 예정에 없던 실제 분류는 `문구`입니다. 집합 연산을 쓰면 반복문으로 하나씩 비교하는 코드보다 의도가 짧게 드러납니다.
빈 집합은 `set()`으로 만듭니다. `{}`는 빈 딕셔너리입니다. 집합의 요소와 딕셔너리의 키에는 해시 가능한 값이 필요합니다. 문자열이나 정수는 사용할 수 있지만 리스트를 그대로 넣을 수는 없습니다. 이번 연재에서는 집합에 분류 이름 같은 문자열만 넣겠습니다.
무엇을 고를까
순서대로 여러 거래를 보관하고 수정한다면 리스트, 필드 이름으로 거래를 읽는다면 딕셔너리, 한 쌍의 반환값처럼 정해진 묶음을 표현한다면 튜플, 중복 없는 분류나 포함 여부가 목적이라면 집합을 생각하면 됩니다. 자료구조 선택은 문법 자랑이 아니라 자료의 의미를 설명하는 일입니다.
직접 해 보기
어제 방문자 목록이 `{"민수", "영희"}`, 오늘이 `{"영희", "철수"}`일 때 이틀 모두 방문한 사람과 오늘 새로 방문한 사람을 출력하세요.
해설
yesterday = {"민수", "영희"}
today = {"영희", "철수"}
print(sorted(yesterday & today))
print(sorted(today - yesterday))결과는 `['영희']`, `['철수']`입니다. 방문 횟수까지 필요하다면 집합만으로는 부족합니다. 중복 제거가 필요한지, 중복 자체도 정보인지 먼저 판단하세요.
COMMENTS
댓글 0
이 글에 대한 의견이나 질문을 남겨 주세요.
등록된 댓글이 없습니다.