파이썬 / / 2025. 5. 25. 00:47

6. 파이썬 집합(SET) 자료형. 여러 예제로 깊게 이해하기.

반응형

파이썬-집합-set-자료형

 

파이썬 집합(Set) 자료형 완전 정복 가이드

집합(Set)은 수학의 집합 개념을 프로그래밍으로 구현한 자료형입니다. 중복된 데이터를 자동으로 제거하고, 집합 연산을 효율적으로 처리할 수 있어 데이터 분석과 알고리즘 문제 해결에 필수적인 도구입니다.

목차

  1. Set 자료형 생성 방법
  2. Set의 핵심 특성
  3. 집합 연산 (교집합, 합집합, 차집합, 대칭차집합)
  4. Set 메서드와 활용법
  5. 실전 예제와 게임 구현

 


 

1. Set 자료형 생성 방법

 

기본 생성 방법

 
python
# 리스트를 이용한 Set 생성
numbers = set([10, 20, 30, 40, 50])
print(numbers)  # {10, 20, 30, 40, 50}

# 문자열을 이용한 Set 생성
letters = set("Python")
print(letters)  # {'P', 'y', 't', 'h', 'o', 'n'}

# 중괄호를 이용한 직접 생성
fruits = {"apple", "banana", "cherry"}
print(fruits)  # {'apple', 'banana', 'cherry'}

# 빈 Set 생성 (주의: {}는 딕셔너리!)
empty_set = set()
print(type(empty_set))  # <class 'set'>

다양한 데이터 타입으로 Set 생성

 
python
# 튜플을 이용한 Set 생성
coordinates = set([(1, 2), (3, 4), (5, 6)])
print(coordinates)  # {(1, 2), (3, 4), (5, 6)}

# 혼합 데이터 타입 Set
mixed_set = {1, "hello", 3.14, True}
print(mixed_set)  # {1, 3.14, 'hello'}  # True는 1과 같아서 제거됨

 

2. Set의 핵심 특성

 

특성 1: 중복 제거 (Uniqueness)

 
python
# 중복된 값이 자동으로 제거됨
duplicate_numbers = [7, 2, 9, 2, 7, 5, 9]
unique_numbers = set(duplicate_numbers)
print(f"원본 리스트: {duplicate_numbers}")
print(f"중복 제거된 Set: {unique_numbers}")

# 실용적인 중복 제거 예제: 학생 명단 정리
student_list = ["김철수", "박영희", "이민수", "김철수", "박영희", "최호진"]
unique_students = list(set(student_list))
print(f"중복 제거된 학생 명단: {unique_students}")

 

특성 2: 순서가 없음 (Unordered)

 
python
# Set은 순서가 없어서 인덱싱 불가
game_scores = {85, 92, 78, 95, 88}
print(game_scores)  # 순서가 매번 다를 수 있음

# 인덱싱을 위해서는 리스트나 튜플로 변환 필요
score_list = list(game_scores)
print(f"첫 번째 점수: {score_list[0]}")
print(f"정렬된 점수: {sorted(score_list)}")

 

3. 집합 연산 완전 정복

 

교집합 (Intersection) - 공통 원소 찾기

 
python
# 두 게임의 공통 플레이어 찾기
game_a_players = {"철수", "영희", "민수", "호진", "수진"}
game_b_players = {"영희", "민수", "지은", "태호", "수진"}

# 방법 1: & 연산자 사용
common_players_1 = game_a_players & game_b_players
print(f"공통 플레이어 (&): {common_players_1}")

# 방법 2: intersection() 메서드 사용
common_players_2 = game_a_players.intersection(game_b_players)
print(f"공통 플레이어 (intersection): {common_players_2}")

# 여러 집합의 교집합
game_c_players = {"민수", "수진", "현우", "보라"}
all_common = game_a_players & game_b_players & game_c_players
print(f"세 게임 모두 참여한 플레이어: {all_common}")

 

합집합 (Union) - 모든 원소 합치기

 
python
# 전체 참가자 명단 만들기
all_participants_1 = game_a_players | game_b_players
print(f"전체 참가자 (|): {all_participants_1}")

all_participants_2 = game_a_players.union(game_b_players)
print(f"전체 참가자 (union): {all_participants_2}")

# 여러 집합의 합집합
total_players = game_a_players.union(game_b_players, game_c_players)
print(f"모든 게임 참가자: {total_players}")

 

차집합 (Difference) - 한쪽에만 있는 원소

 
python
# 게임 A에만 참여한 플레이어
only_game_a = game_a_players - game_b_players
print(f"게임 A 전용 플레이어 (-): {only_game_a}")

only_game_a_2 = game_a_players.difference(game_b_players)
print(f"게임 A 전용 플레이어 (difference): {only_game_a_2}")

# 게임 B에만 참여한 플레이어
only_game_b = game_b_players - game_a_players
print(f"게임 B 전용 플레이어: {only_game_b}")

 

대칭차집합 (Symmetric Difference) - 공통이 아닌 원소

 
python
# 둘 중 하나의 게임에만 참여한 플레이어
exclusive_players_1 = game_a_players ^ game_b_players
print(f"한 게임에만 참여 (^): {exclusive_players_1}")

exclusive_players_2 = game_a_players.symmetric_difference(game_b_players)
print(f"한 게임에만 참여 (symmetric_difference): {exclusive_players_2}")

 

집합 관계 확인 메서드

 
python
# 부분집합과 상위집합 확인
vip_members = {"철수", "영희"}
all_members = {"철수", "영희", "민수", "호진", "수진"}

print(f"VIP가 전체의 부분집합인가? {vip_members.issubset(all_members)}")
print(f"전체가 VIP의 상위집합인가? {all_members.issuperset(vip_members)}")

# 서로소 집합 확인 (공통 원소가 없는지)
group_x = {"A", "B", "C"}
group_y = {"D", "E", "F"}
print(f"두 그룹이 서로소인가? {group_x.isdisjoint(group_y)}")

 

 

 

반응형

 

4. Set 메서드와 활용법

 

원소 추가하기

 
python
# 단일 원소 추가 - add()
shopping_cart = {"우유", "빵", "계란"}
shopping_cart.add("치즈")
print(f"장바구니: {shopping_cart}")

# 여러 원소 추가 - update()
shopping_cart.update(["사과", "바나나", "오렌지"])
print(f"과일 추가 후: {shopping_cart}")

# 다른 Set과 합치기
essential_items = {"쌀", "김치", "라면"}
shopping_cart.update(essential_items)
print(f"필수품 추가 후: {shopping_cart}")

 

원소 제거하기

 
python
inventory = {"컴퓨터", "마우스", "키보드", "모니터", "스피커"}

# remove() - 없으면 오류 발생
inventory.remove("스피커")
print(f"스피커 제거 후: {inventory}")

# discard() - 없어도 오류 없음
inventory.discard("웹캠")  # 없는 항목이지만 오류 없음
inventory.discard("마우스")
print(f"마우스 제거 후: {inventory}")

# pop() - 임의의 원소 제거 후 반환
removed_item = inventory.pop()
print(f"제거된 항목: {removed_item}")
print(f"남은 인벤토리: {inventory}")

# clear() - 모든 원소 제거
backup_inventory = inventory.copy()
inventory.clear()
print(f"초기화된 인벤토리: {inventory}")
print(f"백업된 인벤토리: {backup_inventory}")

 

5. 실전 예제와 게임 구현

 

예제 1: 로또 번호 생성기

 
python
import random

def generate_lotto_numbers():
    """중복 없는 로또 번호 6개를 생성하는 함수"""
    lotto_set = set()
    
    # Set의 크기가 6이 될 때까지 반복
    while len(lotto_set) < 6:
        number = random.randint(1, 45)
        lotto_set.add(number)  # Set이므로 중복은 자동으로 제거됨
    
    return sorted(list(lotto_set))

# 로또 번호 5세트 생성
print("=== 로또 번호 생성기 ===")
for i in range(5):
    numbers = generate_lotto_numbers()
    print(f"{i+1}세트: {numbers}")

 

예제 2: 단어 게임 - 글자 맞추기

 
python
def word_guessing_game():
    """사용자가 단어의 글자를 맞추는 게임"""
    secret_word = "PYTHON"
    secret_letters = set(secret_word.lower())
    guessed_letters = set()
    max_attempts = 10
    attempts = 0
    
    print("=== 글자 맞추기 게임 ===")
    print(f"단어는 {len(secret_word)}글자입니다.")
    print(f"최대 {max_attempts}번의 기회가 있습니다.")
    
    while attempts < max_attempts:
        # 현재 상태 표시
        display_word = ""
        for letter in secret_word.lower():
            if letter in guessed_letters:
                display_word += letter.upper() + " "
            else:
                display_word += "_ "
        
        print(f"\n현재 상태: {display_word}")
        print(f"추측한 글자: {sorted(list(guessed_letters))}")
        print(f"남은 기회: {max_attempts - attempts}")
        
        # 모든 글자를 맞췄는지 확인
        if secret_letters.issubset(guessed_letters):
            print(f"\n축하합니다! 단어는 '{secret_word}'였습니다!")
            break
        
        # 사용자 입력
        guess = input("글자를 입력하세요: ").lower()
        
        if len(guess) != 1 or not guess.isalpha():
            print("한 글자만 입력해주세요!")
            continue
            
        if guess in guessed_letters:
            print("이미 추측한 글자입니다!")
            continue
        
        guessed_letters.add(guess)
        attempts += 1
        
        if guess in secret_letters:
            print("정답입니다!")
        else:
            print("틀렸습니다!")
    
    else:
        print(f"\n게임 오버! 정답은 '{secret_word}'였습니다.")

# 게임 실행 (주석 해제하여 실행)
# word_guessing_game()

 

예제 3: 친구 추천 시스템

 
python
def recommend_friends(user_friends, all_users_friends):
    """공통 친구를 기반으로 친구를 추천하는 시스템"""
    user_name = input("사용자 이름을 입력하세요: ")
    
    if user_name not in all_users_friends:
        print("사용자를 찾을 수 없습니다.")
        return
    
    my_friends = all_users_friends[user_name]
    recommendations = {}
    
    # 모든 다른 사용자들과 공통 친구 수 계산
    for other_user, other_friends in all_users_friends.items():
        if other_user != user_name and other_user not in my_friends:
            # 공통 친구 찾기 (교집합)
            common_friends = my_friends & other_friends
            if common_friends:  # 공통 친구가 있다면
                recommendations[other_user] = common_friends
    
    # 추천 결과 출력
    if recommendations:
        print(f"\n{user_name}님을 위한 친구 추천:")
        for recommended_user, common in recommendations.items():
            print(f"- {recommended_user} (공통 친구: {', '.join(common)})")
    else:
        print("추천할 친구가 없습니다.")

# 사용자별 친구 목록 (실제로는 데이터베이스에서 가져올 것)
friends_database = {
    "철수": {"영희", "민수", "호진"},
    "영희": {"철수", "수진", "지은"},
    "민수": {"철수", "태호", "보라"},
    "호진": {"철수", "현우"},
    "수진": {"영희", "지은", "태호"},
    "지은": {"영희", "수진"},
    "태호": {"민수", "수진", "현우"},
    "보라": {"민수"},
    "현우": {"호진", "태호"}
}

print("=== 친구 추천 시스템 ===")
recommend_friends(friends_database, friends_database)

 

예제 4: 재고 관리 시스템

 
python
class InventoryManager:
    """Set을 활용한 간단한 재고 관리 시스템"""
    
    def __init__(self):
        self.warehouse_a = set()
        self.warehouse_b = set()
        self.reserved_items = set()
    
    def add_items(self, warehouse, items):
        """창고에 상품 추가"""
        if warehouse == 'A':
            self.warehouse_a.update(items)
        elif warehouse == 'B':
            self.warehouse_b.update(items)
        print(f"창고 {warehouse}에 상품 추가 완료: {items}")
    
    def reserve_items(self, items):
        """상품 예약"""
        available_items = self.warehouse_a | self.warehouse_b
        reservable = set(items) & available_items
        
        if reservable == set(items):
            self.reserved_items.update(items)
            print(f"예약 완료: {items}")
        else:
            unavailable = set(items) - available_items
            print(f"예약 실패 - 재고 없음: {unavailable}")
    
    def get_status(self):
        """재고 현황 조회"""
        print("\n=== 재고 현황 ===")
        print(f"창고 A: {self.warehouse_a}")
        print(f"창고 B: {self.warehouse_b}")
        print(f"예약된 상품: {self.reserved_items}")
        
        # 각 창고 전용 상품
        only_a = self.warehouse_a - self.warehouse_b
        only_b = self.warehouse_b - self.warehouse_a
        common_items = self.warehouse_a & self.warehouse_b
        
        print(f"창고 A 전용: {only_a}")
        print(f"창고 B 전용: {only_b}")
        print(f"공통 재고: {common_items}")
        
        # 예약 가능한 상품
        available = (self.warehouse_a | self.warehouse_b) - self.reserved_items
        print(f"예약 가능: {available}")

# 재고 관리 시스템 사용 예제
inventory = InventoryManager()

# 창고에 상품 추가
inventory.add_items('A', ["노트북", "마우스", "키보드", "모니터"])
inventory.add_items('B', ["마우스", "스피커", "웹캠", "모니터"])

# 현황 확인
inventory.get_status()

# 상품 예약
inventory.reserve_items(["노트북", "스피커"])
inventory.reserve_items(["태블릿"])  # 없는 상품

# 최종 현황
inventory.get_status()

 

정리 테이블

연산/메서드기호설명예제

교집합 & 또는 intersection() 공통 원소 {1,2,3} & {2,3,4} → {2,3}
합집합 ` 또는union()` 모든 원소
차집합 - 또는 difference() 한쪽에만 있는 원소 {1,2,3} - {2,3,4} → {1}
대칭차집합 ^ 또는 symmetric_difference() 공통이 아닌 원소 {1,2,3} ^ {2,3,4} → {1,4}
원소 추가 add() 단일 원소 추가 s.add(5)
여러 원소 추가 update() 여러 원소 추가 s.update([4,5,6])
원소 제거 remove() 없으면 오류 s.remove(3)
안전한 제거 discard() 없어도 오류 없음 s.discard(3)

 

Set 자료형은 데이터의 중복을 제거하고 집합 연산을 효율적으로 처리할 수 있는 강력한 도구입니다. 특히 데이터 분석, 알고리즘 문제 해결, 그리고 실제 업무에서 매우 유용하게 활용할 수 있습니다.

반응형
  • 네이버 블로그 공유
  • 네이버 밴드 공유
  • 페이스북 공유
  • 카카오스토리 공유