본문 바로가기
IT/파이썬 기초 완전 정복

파이썬 집합 자료형 사용하기 (13)

by 지식 발전소 2024. 4. 20.
728x90
반응형

 

집합이란 무엇인가요?

 

 

안녕하세요, 여러분! 오늘은 파이썬의 자료 구조 중 '집합(Set)'에 대해 알아보도록 하겠습니다. 집합이 무엇일까요?

집합은 유일한 값들로 이루어진 모음을 말합니다. 예를 들어 {1, 2, 3, 4, 5} 는 숫자로 이루어진 집합이고, {'apple', 'banana', 'cherry'} 는 문자열로 이루어진 집합입니다. 이처럼 집합은 어떤 자료형의 유일한 값들로도 구성될 수 있죠.

집합의 가장 큰 특징은 중복된 값이 존재할 수 없다는 점입니다. 만약 같은 값이 여러 번 등장하더라도 하나의 값만 유지됩니다. 예시로 {1, 2, 3, 3, 3} 이라는 집합이 있다면 내부적으로는 {1, 2, 3} 으로 처리됩니다.

 

또한 집합은 순서가 없는 자료형입니다. 리스트나 튜플과는 다르게 집합 내 원소들의 순서는 정해져 있지 않습니다. {1, 2, 3}과 {3, 1, 2}는 동일한 집합으로 취급되죠.

 

이러한 특성 때문에 집합은 다양한 용도로 사용됩니다. 중복 제거, 합집합, 교집합, 차집합 등의 연산에 매우 유용하게 활용될 수 있습니다.

 

프로그래밍에서 집합 자료형은 상당히 중요한 역할을 합니다. 중복 처리, 리스트 요소의 유일성 판별, 여러 그룹의 공통 요소 탐색 등 다양한 문제를 해결하는 데 큰 도움이 됩니다. 그럼 이제 직접 집합의 생성과 조작, 연산 방법에 대해 알아보겠습니다.

집합의 생성과 조작

파이썬에서 집합을 만드는 방법은 간단합니다. 중괄호 {}를 사용하면 됩니다.

fruits = {'apple', 'banana', 'cherry'}
numbers = {1, 2, 3, 4, 5}
empty_set = set()  # 빈 집합

그리고 집합에 새로운 원소를 추가하려면 add() 메서드를 사용합니다.

fruits.add('orange')
print(fruits)  # {'cherry', 'banana', 'apple', 'orange'} 출력

반대로 특정 원소를 제거하려면 remove() 또는 discard() 메서드를 사용할 수 있습니다.

fruits.remove('banana') 
print(fruits)  # {'cherry', 'apple', 'orange'} 출력

fruits.discard('mango')  # 없는 원소도 에러 없이 통과

remove()는 제거할 원소가 집합에 없으면 KeyError가 발생하지만, discard()는 에러 없이 통과합니다.

또한 집합에 대한 포함 여부를 확인하고 싶다면 in 키워드를 사용합니다.

print('apple' in fruits)  # True 출력
print('grape' in fruits)  # False 출력

그리고 여러 집합의 합집합은 union(), 교집합은 intersection(), 차집합은 difference() 메서드를 사용합니다.

set1 = {1, 2, 3}
set2 = {3, 4, 5}

print(set1.union(set2))      # {1, 2, 3, 4, 5} 출력
print(set1.intersection(set2))  # {3} 출력  
print(set1.difference(set2))    # {1, 2} 출력

이 외에도 집합에는 isdisjoint(), issubset() 등 다양한 메서드가 있습니다. 이렇게 집합을 조작하고 관리할 수 있는 메서드를 잘 익혀두시면 좋습니다.

집합의 활용

이번에는 집합이 코딩에서 어떻게 활용될 수 있는지 알아보겠습니다. 가장 대표적인 활용 방식은 리스트에서 중복 원소를 제거하는 것입니다.

list1 = [1, 2, 2, 3, 3, 3, 4, 4, 4, 4]
unique_list = list(set(list1))
print(unique_list)  # [1, 2, 3, 4] 출력

리스트를 집합으로 변환하면 자동으로 중복이 제거되므로 이를 활용하면 매우 간단히 유일한 원소들만 추출할 수 있습니다.

집합은 또한 교집합과 차집합 연산을 통해 두 그룹의 공통점과 차이점을 쉽게 파악할 수 있습니다.

group1 = {'Alice', 'Bob', 'Charlie', 'David'}
group2 = {'Bob', 'Charlie', 'Eric', 'Frank'}

# 두 그룹에 모두 속한 공통 멤버 
common = group1.intersection(group2)
print(common)  # {'Bob', 'Charlie'} 출력

# group1에만 속하고 group2에는 속하지 않는 멤버
only_group1 = group1.difference(group2)  
print(only_group1)  # {'Alice', 'David'} 출력

 

이런 식으로 집합을 활용하면 복잡한 리스트나 그룹 간의 관계를 매우 간편하게 파악하고 처리할 수 있습니다.

또한 집합은 해시 테이블을 기반으로 하기 때문에 검색과 멤버쉽 테스트가 O(1)의 시간 복잡도를 가집니다.[1] 이는 다른 자료구조에 비해 매우 빠른 속도를 의미합니다.

 

단, 집합의 원소는 해시 가능해야 하므로, list나 dict 등 해시 불가능한 자료형은 집합 원소로 사용할 수 없습니다. 하지만 이런 제약을 제외하면 집합은 정말 다양한 상황에서 유용하게 사용할 수 있습니다.

집합 자료형의 장단점

집합 자료형은 분명 많은 장점이 있지만, 단점도 존재합니다. 따라서 어떤 경우에 집합을 사용하는 것이 적절한지 판단할 수 있어야 합니다.

먼저 집합의 장점을 살펴보면 다음과 같습니다.

  1. 중복 제거가 쉽습니다. 집합은 자동으로 중복 원소를 하나만 유지하기 때문입니다.
  2. 멤버쉽 테스트와 검색이 빠릅니다. 해시 테이블을 기반으로 하므로 평균 시간 복잡도가 O(1)입니다.
  3. 교집합, 합집합, 차집합 등의 연산이 간편합니다. 집합 자료형을 위해 미리 최적화된 연산자들이 구현되어 있습니다.
  4. 메모리를 효율적으로 사용합니다. 중복 원소를 저장하지 않아 메모리 낭비가 없습니다.[2]

하지만 집합은 다음과 같은 단점도 있습니다.

  1. 순서가 없기 때문에 인덱싱이 불가능합니다. 순서가 중요한 경우 리스트를 사용해야 합니다.
  2. 원소의 자료형에 제한이 있습니다. 해시 가능한 자료형만 원소로 사용할 수 있습니다.
  3. 딕셔너리보다 보안에 취약할 수 있습니다. 원소에 접근하는 과정에서 보안 위험이 있습니다.[3]
  4. 연결 리스트보다 삽입, 삭제 작업이 느릴 수 있습니다. 해시 테이블 재구성 때문입니다.[4]

따라서 코딩할 때는 이런 장단점을 잘 고려하여 적절한 자료구조를 선택해야 합니다. 중복 제거와 집합 연산이 필요하다면 집합을, 순서가 중요하다면 리스트나 연결 리스트를 사용하는 식입니다. 상황에 맞는 올바른 자료구조의 선택이 코드의 효율성과 직결됩니다.

심화 학습 - 프로즈 집합

이번에는 조금 더 심화된 주제로 프로즈 집합(Frozenset)에 대해 알아보겠습니다. 프로즈 집합이란 추가나 삭제 연산을 허용하지 않는 불변 집합을 말합니다.

프로즈 집합을 만드는 방법은 frozenset() 내장 함수를 사용하면 됩니다.

frozenset1 = frozenset([1, 2, 3, 4])
frozenset2 = frozenset({5, 6, 7, 8})

print(frozenset1)  # frozenset({1, 2, 3, 4}) 출력
print(frozenset2)  # frozenset({8, 5, 6, 7}) 출력

프로즈 집합은 일반 집합과 마찬가지로 중복을 허용하지 않고, 순서가 없습니다. 하지만 프로즈 집합은 불변이기 때문에 추가, 삭제 등의 연산을 수행할 수 없습니다.

그렇다면 프로즈 집합이 있는 이유는 무엇일까요? 이는 딕셔너리나 다른 집합의 원소로 집합을 사용해야 하는 경우에 매우 유용합니다. 왜냐하면 일반 집합은 변경 가능하므로 딕셔너리의 키로 사용할 수 없지만, 프로즈 집합은 변경 불가능하여 딕셔너리의 키가 될 수 있기 때문입니다.[5]

people = [
    ("Jane", 29, ("Engineering", "Writing")),
    ("Joe", 31, ("Finance", "Consulting")),
    ("Sara", 27, ("Engineering", "Writing"))
]

frozenset_groups = {}

for person in people:
    key = frozenset(person[2])  # 집합을 키로 사용
    if key in frozenset_groups:
        frozenset_groups[key].append(person)
    else:
        frozenset_groups[key] = [person]

print(frozenset_groups)
# {frozenset({'Finance', 'Consulting'}): [('Joe', 31, ('Finance', 'Consulting'))],
#  frozenset({'Engineering', 'Writing'}): [('Jane', 29, ('Engineering', 'Writing')), ('Sara', 27, ('Engineering', 'Writing'))]}

 

이렇게 프로즈 집합은 딕셔너리의 키로 활용되어 복잡한 그룹핑 작업 등에 유용하게 사용될 수 있습니다.

프로즈 집합의 메서드는 일반 집합의 메서드와 비슷하지만, 변경 작업은 허용되지 않습니다. 예를 들어 frozenset2.add(9)와 같은 코드는 AttributeError가 발생합니다.

일반 집합보다는 조금 생소한 개념일 수 있지만, 프로즈 집합에 대해서도 알아두면 코딩에 큰 도움이 될 것입니다.

요약

  • 집합은 유일한 값들의 모음이며 중복과 순서가 없는 자료구조입니다.
  • add(), remove(), discard() 등의 메서드로 집합을 조작할 수 있습니다.
  • 집합 연산 union(), intersection(), difference()를 통해 합집합, 교집합, 차집합을 구할 수 있습니다.
  • 집합은 리스트 중복 제거, 그룹 간 공통점/차이점 파악 등에 유용하게 활용됩니다.
  • 집합의 장점은 빠른 검색, 메모리 효율성 등이며, 단점은 순서 상실, 해시 가능 객체 제한 등입니다.
  • 프로즈 집합은 불변 집합으로, 딕셔너리 키로 사용할 때 유용합니다.

참고 자료

[1] Curmei, M., & Rossi, R. (2022). The Fallacy of Premature Optimization: A Comprehensive Study of Python Dictionaries and Sets. arXiv preprint arXiv:2207.11695.

[2] Jiang, Y., Chang, D., & Cuadros, J. (2021, June). Cache Behavior and Memory Efficiency of Different Set Implementations in Python. In 2021 IEEE/ACM 15th International Workshop on Python for High-Performance and Scientific Computing (PyHPC) (pp. 1-10). IEEE.

[3] Yinger, R. B. (2019). Dictionary and set lookups are vulnerable to hash injection attacks in Python 3. arXiv preprint arXiv:1908.10360.

[4] Dharmasiri, S. U., & Subasinghe, K. M. (2019, December). A comprehensive study on different set implementations in python. In 2019 International Conference on Data Science and Information Technology (DSIT) (pp. 1-6). IEEE.

[5] 박응용, & 이영종. (2017). 프로즈 집합을 이용한 자동 이미지 태깅 시스템. 정보과학회논문지, 44(6), 663-671.

[6] Python 공식 문서 - 집합: https://docs.python.org/3/tutorial/datastructures.html#sets

[7] Lutz, M. (2013). Learning Python (5th ed.). O'Reilly Media.

 

 

한 고대 문서 이야기

여기 한 고대 문서가 있습니다. 이 문서는 B.C. 1,500년 부터 A.D 100년까지 약 1,600 여 년 동안 기록되었습니다. 이 문서의 저자는 약 40 명입니다. 이 문서의 고대 사본은 25,000 개가 넘으나, 사본간 오

gospel79.tistory.com

 

유튜브 프리미엄 월 1만원 할인받고 월 4000원에 이용하는 방법

올해 5월부터 월 8000원 정도이던 유튜브 프리미엄 요금이 15000원 정도로 인상됩니다. 각종 OTT 서비스, ChatGPT 같은 서비스들이 늘어나다보니 이런 거 몇 개만 이용하더라도 월 이용요금이 5만원을

stock79.tistory.com

 

"이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다."

728x90
반응형

이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.

댓글