Computer >> 컴퓨터 >  >> 프로그래밍 >> Python

파이썬 세트(Set) 완벽 가이드: 생성부터 수정, 집합 연산까지

데이터를 다룰 때 중복 값이 없어야 하고, 저장된 값이 함부로 변경되지 않아야 하는 목록이 필요한 경우가 자주 있습니다. 예를 들어 마트에서 판매되는 상품 ID 목록을 만든다면 각 ID는 반드시 고유해야 하며, 누군가 목록 안의 값을 임의로 바꾸지 못하도록 해야겠죠.

바로 이럴 때 파이썬 세트(set)가 유용합니다. 세트는 고유한(unique) 값만 담을 수 있는 순서 없는 컬렉션입니다.

이 튜토리얼에서는 파이썬 세트의 기본 개념과 함께, 요소를 추가하거나 삭제하는 등 세트에서 자주 사용하는 연산 방법을 예제와 함께 살펴보겠습니다.

파이썬 세트란 무엇인가?

파이썬에 내장된 세트(set) 자료구조는 수학에서 말하는 '집합' 개념과 매우 유사합니다.

세트는 0개 이상의 요소를 가질 수 있으며, 요소들 사이에는 특별한 순서가 존재하지 않습니다. 또한 세트에 저장되는 모든 요소는 고유해야 하기 때문에 중복이 허용되지 않고, 한 번 저장된 개별 값은 변경할 수 없습니다.

다만 개별 값은 변경할 수 없어도 세트 자체에는 요소를 추가하거나 제거하는 것이 가능합니다.

세트는 수학적 집합 연산(합집합, 교집합, 차집합 등)을 기본으로 지원하기 때문에 데이터를 다루기에 매우 편리한 자료구조입니다.

파이썬 세트 만들기

파이썬에서 세트는 쉼표로 구분된 항목(요소)들을 중괄호 {}로 감싸서 정의합니다.

세트에는 여러 개의 항목을 저장할 수 있으며, 각 항목은 서로 다른 데이터 타입이어도 됩니다. 즉, 하나의 세트에 정수와 문자열을 함께 넣거나, 문자열·실수·튜플을 섞어 저장할 수도 있습니다. 단, 세트는 변경 가능한(mutable) 자료형인 리스트, 딕셔너리, 그리고 다른 세트는 저장할 수 없다는 점에 주의해야 합니다.

예를 들어, 영어 수업에서 학생이 제출한 과제 목록을 세트로 관리한다고 가정해 봅시다. 다음과 같이 코드를 작성할 수 있습니다.

assignments = {"Worksheet #4", "Worksheet #5", "Worksheet #7", "End of Topic Review #2"}
print(assignments)

실행 결과:

{'Worksheet #5', 'Worksheet #4', 'Worksheet #7', 'End of Topic Review #2'}

위 코드에서는 네 개의 값을 가진 assignments라는 이름의 세트를 정의하고, 그 내용을 콘솔에 출력했습니다. 출력 결과에서 값들이 무작위 순서로 반환되는 것을 확인할 수 있는데, 이는 세트가 항목을 특정 순서로 저장하지 않기 때문입니다.

세트 수정하기

세트를 한 번 만들면 세트 안에 있는 개별 값의 내용은 변경할 수 없습니다. 하지만 새로운 항목을 추가하거나 기존 항목을 제거하는 것은 언제든 가능합니다.

세트에 항목 추가하기

세트에 요소를 하나 추가할 때는 add() 메서드를 사용합니다. 학생이 방금 'Worksheet #8'을 제출했고, 이를 과제 목록에 반영하고 싶다면 다음과 같이 작성하면 됩니다.

assignments = {"Worksheet #4", "Worksheet #5", "Worksheet #7", "End of Topic Review #2"}

assignments.add("Worksheet #8")
print(assignments)

실행 결과:

{'Worksheet #8', 'Worksheet #4', 'Worksheet #5', 'End of Topic Review #2', 'Worksheet #7'}

'Worksheet #8'이 세트에 성공적으로 추가된 것을 확인할 수 있습니다.

여러 항목을 한 번에 추가하고 싶다면 update() 메서드를 사용하세요. 이 메서드는 추가하고자 하는 항목들의 목록을 인자로 받아 해당 항목들을 모두 세트에 더해 줍니다.

예를 들어 학생이 Worksheet #8과 #9 두 개를 동시에 제출했다면 다음 코드로 처리할 수 있습니다.

assignments = {"Worksheet #4", "Worksheet #5", "Worksheet #7", "End of Topic Review #2"}

assignments.update(["Worksheet #8", "Worksheet #9"])
print(assignments)

실행 결과:

{'Worksheet #9', 'End of Topic Review #2', 'Worksheet #8', 'Worksheet #7', 'Worksheet #4', 'Worksheet #5'}

이제 세트에는 'Worksheet #8'과 'Worksheet #9'라는 두 개의 새로운 값이 포함되어 있습니다.

세트에서 항목 삭제하기

세트에서 요소를 제거할 때는 discard() 또는 remove() 메서드를 사용할 수 있습니다.

두 메서드의 차이는 다음과 같습니다.

  • discard(): 항목을 제거하되, 해당 항목이 세트에 존재하지 않으면 아무런 오류도 발생하지 않습니다.
  • remove(): 항목을 제거하려 시도하고, 해당 항목이 존재하지 않으면 오류(KeyError)가 발생합니다.

학생이 'Worksheet #9'를 재제출하도록 안내받았다고 가정하고, 해당 항목을 목록에서 삭제해 보겠습니다.

assignments = {'Worksheet #9', 'End of Topic Review #2', 'Worksheet #8', 'Worksheet #7', 'Worksheet #4', 'Worksheet #5'}

assignments.discard("Worksheet #9")
print(assignments)

실행 결과:

{'End of Topic Review #2', 'Worksheet #5', 'Worksheet #4', 'Worksheet #8', 'Worksheet #7'}

'Worksheet #9'가 세트에서 성공적으로 제거된 것을 볼 수 있습니다.

세트 비우기

세트 전체를 비우고 싶다면 clear() 메서드를 사용합니다. 연말이 되어 더 이상 학생의 과제 정보를 보관할 필요가 없다면 다음 코드처럼 세트를 초기화할 수 있습니다.

assignments = {'Worksheet #9', 'End of Topic Review #2', 'Worksheet #8', 'Worksheet #7', 'Worksheet #4', 'Worksheet #5'}

assignments.clear()
print(assignments)

실행 결과는 {}이며, 이것이 비어 있는 세트(empty set)입니다.

세트의 길이 구하기

세트에 몇 개의 항목이 저장되어 있는지 확인하려면 len() 함수를 사용합니다.

예를 들어 학생이 제출한 과제가 총 몇 개인지 알고 싶다면 다음과 같이 작성할 수 있습니다.

assignments = {'Worksheet #9', 'End of Topic Review #2', 'Worksheet #8', 'Worksheet #7', 'Worksheet #4', 'Worksheet #5'}
print(len(assignments))

실행 결과: 6

먼저 assignments 세트를 선언한 뒤, len() 함수로 해당 세트에 저장된 항목의 개수를 확인했습니다.

파이썬 세트 연산

세트를 사용하는 가장 큰 장점 중 하나는 수학적 집합 연산을 지원한다는 점입니다. 대표적인 세 가지 집합 연산의 사용법을 살펴보겠습니다.

참고로 이러한 집합 연산들은 원본 세트의 내용을 변경하지 않습니다. 대신 계산 결과를 새로운 세트로 반환합니다.

합집합(Union)

union() 메서드를 사용하면 두 세트의 모든 요소를 포함하는 새로운 세트를 만들 수 있습니다.

예를 들어 학생의 과제 목록 두 개를 하나로 합친다고 가정해 봅시다. 하나는 숙제 목록이고, 다른 하나는 완료한 에세이 목록입니다. 다음 코드로 두 목록을 병합할 수 있습니다.

assignments = {"Worksheet #4", "Worksheet #5", "Worksheet #7"}
essays = {"Essay #1", "Essay #2"}

homework = assignments.union(essays)
print(homework)

실행 결과:

{'Worksheet #7', 'Essay #2', 'Worksheet #4', 'Essay #1', 'Worksheet #5'}

위 코드에서는 union() 메서드로 두 세트를 병합하고, 결과를 homework 변수에 할당한 후 출력했습니다.

같은 작업은 | 연산자로도 수행할 수 있습니다.

assignments = {"Worksheet #4", "Worksheet #5", "Worksheet #7"}
essays = {"Essay #1", "Essay #2"}

print(assignments | essays)

| 연산자는 합집합 연산을 수행하며, 위 코드 역시 병합된 세트를 반환합니다.

교집합(Intersection)

intersection() 메서드를 사용하면 두 세트에 공통으로 존재하는 요소들만 추출할 수 있습니다.

예를 들어 학생이 제출한 에세이 목록과 교사가 부여한 에세이 목록이 있을 때, 두 목록의 교집합을 구해 보겠습니다.

essays_handed_in = {"Essay #1", "Essay #2"}
essays_issued = {"Essay #1", "Essay #2", "Essay #3"}

due = essays_handed_in.intersection(essays_issued)
print(due)

실행 결과:

{'Essay #1', 'Essay #2'}

이 예제에서는 intersection() 메서드로 essays_handed_inessays_issued 두 세트에 공통으로 존재하는 요소를 찾고, 결과를 due 변수에 할당하여 콘솔에 출력했습니다.

마찬가지로 & 연산자를 사용해 교집합을 구할 수도 있습니다.

essays_handed_in = {"Essay #1", "Essay #2"}
essays_issued = {"Essay #1", "Essay #2", "Essay #3"}

print(essays_handed_in & essays_issued)

실행 결과:

{'Essay #1', 'Essay #2'}

차집합(Difference)

difference() 메서드를 사용하면 한 세트에는 있지만 다른 세트에는 없는 요소를 찾을 수 있습니다.

예를 들어 학생이 제출했지만 아직 채점되지 않은 에세이 목록을 만들고 싶다면 다음 코드를 사용할 수 있습니다.

essays_handed_in = {"Essay #1", "Essay #2"}
essays_graded = {"Essay #1"}

final = essays_handed_in.difference(essays_graded)
print(final)

실행 결과:

{'Essay #2'}

이 코드에서는 difference() 메서드로 essays_handed_inessays_graded 세트의 차집합을 구했습니다. 같은 결과는 - 연산자로도 얻을 수 있습니다.

essays_handed_in = {"Essay #1", "Essay #2"}
essays_graded = {"Essay #1"}
print(essays_handed_in - essays_graded)

실행 결과:

{'Essay #2'}

메서드 대신 - 연산자를 사용했을 뿐, 동일한 결과가 반환됩니다.

마무리

파이썬의 세트 자료구조는 순서 없는 컬렉션을 저장할 수 있게 해 줍니다.

세트의 핵심 특징을 정리하면 다음과 같습니다.

  • 모든 항목은 고유해야 하므로 중복이 존재할 수 없습니다.
  • 항목은 순서 없이 저장됩니다.
  • 개별 값은 변경할 수 없지만, 요소의 추가와 제거는 가능합니다.
  • 합집합, 교집합, 차집합 등 다양한 집합 연산을 지원합니다.

이 튜토리얼에서는 파이썬 세트의 기본 개념과 주요 연산을 예제와 함께 살펴봤습니다. 물론 세트로 할 수 있는 일은 이것보다 훨씬 많지만, 실무에서 세트를 효과적으로 활용하기 위해 꼭 알아야 할 핵심 스킬들은 모두 다뤘습니다. 이제 여러분도 set()을 능숙하게 활용할 준비가 되었습니다!