9강 / 20강
집합 연산 — 명단을 겹치고 빼기
재입고 알림 대상 · VIP 교집합 · 이탈 고객 뽑아내기
마케팅 팀에서 요청이 왔습니다.
"지난달에 산 사람 중에서, 이번 달에는 안 산 사람한테만 쿠폰을 보내 주세요. 단, 이미 VIP 쿠폰 받은 사람은 빼고요."
회원이 50만 명입니다. 이걸 어떻게 뽑을까요?
반복문을 세 겹 쓰면… O(n³)입니다. 며칠 걸려요. 집합(set)을 쓰면 몇 초에 끝납니다.
세 겹 반복문이 한 줄이 됩니다.
Python
브라우저에서 실행
왜 이렇게 빠를까요
집합은 내부적으로 해시 테이블입니다.
x in 집합은 O(1)이에요. 그래서:
- 리스트로 교집합 구하기 → 각 원소마다 상대 리스트를 훑음 → O(n × m)
- 집합으로 교집합 구하기 → 각 원소를 O(1)로 확인 → O(n + m)
in 연산자 하나가 리스트냐 집합이냐에 따라 O(n) vs O(1).
Python
브라우저에서 실행
🎮 고객 명단 집합 연산기
세 개의 고객 명단을 켜고 끄면서 벤 다이어그램이 어떻게 변하는지 보세요. 연산 버튼을 누르면 실제 대상 명단과 파이썬 코드가 함께 나옵니다.
실전 — 재입고 알림 보내기
품절이던 상품이 입고됐습니다. 알림 신청자에게 문자를 보내야 하는데, 이미 산 사람과 탈퇴한 사람은 빼야 합니다.
빼기(-)를 연달아 쓰면 제외 조건을 계속 붙일 수 있습니다.
Python
브라우저에서 실행
🤔 확인 문제
"지난달에 샀지만 이번 달엔 안 산 고객"을 뽑는 집합 연산은?
해설 차집합입니다. 반대로
이번달 - 지난달은 신규 고객이에요.🤔 확인 문제
30,000명과 30,000명 명단의 교집합을 구할 때, 리스트 대신 집합을 쓰면 좋은 이유는?
해설 핵심은 in 연산의 비용입니다. 집합은 해시 테이블이라 O(1). 9억 번이 6만 번이 됩니다.
🤔 확인 문제
집합을 쓸 때 잃어버리는 정보는?
해설 집합은 순서 없음 · 중복 없음입니다. "이 고객이 몇 번 샀는지"가 필요하면
Counter를 쓰세요.