https://school.programmers.co.kr/learn/courses/30/lessons/68644
✳️ 코드 작성
🤔 코드 아이디어
1. 빈 집합 생성 (중복을 제거하기 위해)
2. 입력 리스트에서 두 개의 숫자를 선택 - 이중 for문
3. 선택한 두 수의 합을 집합에 추가
4. 모든 경우의 수에 대해 합을 구함
5. 결과 반환 - 집합을 리스트로 변환하여 오름차순으로 정렬
💟 코드 풀이
def solution(numbers):
answer = set()
for i in range(len(numbers)):
for j in range(i+1, len(numbers)):
answer.add(numbers[i] + numbers[j])
return sorted(list(answer))
🟣 set
- answer라는 빈 집합(set)을 생성
- 집합은 중복을 허용하지 않기 때문에 두 숫자를 더한 값이 중복되더라도 자동으로 제거
더보기
🔖 set !
- 집합을 나타내는 데이터 타입
- 집합과 유사하게, set은 중복되지 않는 요소들의 모음
💭 주요 특징
- 중복 허용 안 함
- set은 같은 값을 여러 번 저장할 수 없음
- 만약 중복된 값을 추가하려고 하면, 하나만 저장
- 순서가 없음
- set은 순서가 없기 때문에 인덱싱(indexing)이나 슬라이싱(slicing)을 할 수 없음
- 요소들이 어떤 순서로 저장될지 보장되지 않음
- 변경 가능
- set은 요소를 추가하거나 제거할 수 있는 mutable한 자료형
- 빠른 탐색
- 집합에 특정 값이 있는지 확인할 때 리스트보다 훨씬 빠른 시간 복잡도를 가짐
- 리스트는 O(n)인 반면, set은 평균적으로 O(1)의 시간 복잡도
🪄 set 함수 사용법
1️⃣ 집합 만들기
# 리스트나 튜플을 집합으로 변환
numbers = [1, 2, 3, 4, 4, 5]
unique_numbers = set(numbers) # 중복된 4는 한 번만 저장됨
print(unique_numbers) # {1, 2, 3, 4, 5}
# 중괄호를 이용한 집합 생성
my_set = {1, 2, 3, 3, 4}
print(my_set) # {1, 2, 3, 4}
2️⃣ 집합에 요소 추가 및 제거
- 추가하기 (add)
my_set = {1, 2, 3}
my_set.add(4) # 4를 추가
print(my_set) # {1, 2, 3, 4}
- 제거하기 (remove, discard)
my_set.remove(2) # 2를 제거
print(my_set) # {1, 3, 4}
# remove는 없는 요소를 제거하려고 할 때 에러가 발생하지만,
# discard는 에러 없이 넘어감
my_set.discard(5) # 에러 발생하지 않음
3️⃣ 집합의 연산
- 합집합 (union) : 두 집합의 모든 요소를 포함한 집합
set1 = {1, 2, 3}
set2 = {3, 4, 5}
print(set1.union(set2)) # {1, 2, 3, 4, 5}
- 교집합 (intersection) : 두 집합에 공통으로 있는 요소들
print(set1.intersection(set2)) # {3}
- 차집합 (difference) : 첫 번째 집합에는 있지만 두 번째 집합에는 없는 요소들
print(set1.difference(set2)) # {1, 2}
- 대칭 차집합 (symmetric_difference) : 두 집합 중 한 쪽에만 있는 요소들
print(set1.symmetric_difference(set2)) # {1, 2, 4, 5}
4️⃣ 기타
- len() : 집합의 크기 구하기
print(len(set1)) # 3
- in : 집합에 특정 요소가 있는지 확인
print(2 in set1) # True
- clear() : 집합의 모든 요소를 제거
set1.clear()
print(set1) # set()
🟣 이중 for문
- 첫 번째 for 루프에서는 리스트 numbers의 각 요소에 대해 인덱스 i를 순회
- 두 번째 for 루프에서는 i+1부터 리스트 끝까지 인덱스 j를 순회
- numbers[i]와 numbers[j]의 합을 answer 집합에 추가
🟣 sorted(list(answer))
- 중복이 제거된 합들을 리스트로 변환
- 리스트를 오름차순으로 정렬해서 반
💠 예시
🔵 입력 예시
numbers = [2, 1, 3, 4, 1]
solution(numbers)
🔵 작동 원리
1️⃣ answer = set()
- 먼저 빈 집합 answer가 생성. answer는 두 숫자의 합을 저장하며, 중복된 값은 자동으로 제거
2️⃣ 이중 for문
- len(numbers)는 5이므로, i는 0부터 4까지 순회
- 각각의 값에 대해 j는 항상 i+1부터 시작해 numbers 리스트 끝까지 비교
⚙️ 세부 실행 과정
i = 0 (numbers[0] = 2)일 때
- j = 1 -> numbers[1] = 1
- numbers[0] + numbers[1] = 2 + 1 = 3
- answer에 3을 추가: answer = {3}
- j = 2 -> numbers[2] = 3
- numbers[0] + numbers[2] = 2 + 3 = 5
- answer에 5를 추가: answer = {3, 5}
- j = 3 -> numbers[3] = 4
- numbers[0] + numbers[3] = 2 + 4 = 6
- answer에 6을 추가: answer = {3, 5, 6}
- j = 4 -> numbers[4] = 1
- numbers[0] + numbers[4] = 2 + 1 = 3
- 3은 이미 집합에 있기 때문에 추가되지 않음 : answer = {3, 5, 6}
i = 1 (numbers[1] = 1)일 때
- j = 2 -> numbers[2] = 3
- numbers[1] + numbers[2] = 1 + 3 = 4
- answer에 4를 추가: answer = {3, 4, 5, 6}
- j = 3 -> numbers[3] = 4
- numbers[1] + numbers[3] = 1 + 4 = 5
- 5는 이미 집합에 있기 때문에 추가되지 않음 : answer = {3, 4, 5, 6}
- j = 4 -> numbers[4] = 1
- numbers[1] + numbers[4] = 1 + 1 = 2
- answer에 2를 추가 : answer = {2, 3, 4, 5, 6}
i = 2 (numbers[2] = 3)일 때
- j = 3 -> numbers[3] = 4
- numbers[2] + numbers[3] = 3 + 4 = 7
- answer에 7을 추가: answer = {2, 3, 4, 5, 6, 7}
- j = 4 -> numbers[4] = 1
- numbers[2] + numbers[4] = 3 + 1 = 4
- 4는 이미 집합에 있기 때문에 추가되지 않음 : answer = {2, 3, 4, 5, 6, 7}
i = 3 (numbers[3] = 4)일 때
- j = 4 -> numbers[4] = 1
- numbers[3] + numbers[4] = 4 + 1 = 5
- 5는 이미 집합에 있기 때문에 추가되지 않음 : answer = {2, 3, 4, 5, 6, 7}
i = 4 (numbers[4] = 1)일 때
- j가 i+1인 5부터 시작되어야 하는데,
이때 numbers의 길이가 5이므로, j는 존재하지 않으므로 for문이 실행되지 않고 넘어감
🔵 최종 반환
- answer가 {2, 3, 4, 5, 6, 7}에서 [2, 3, 4, 5, 6, 7]로 변환
- set을 리스트로 변환, 리스트를 오름차순으로 정렬하여 반환 됨
return sorted(list(answer))
# [2, 3, 4, 5, 6, 7]
💟 리스트 컴프리헨션 + combinations 함수
- itertools 모듈 속 combinations 함수를 통해 이중 for문을 대신하여 불필요한 연산이었던 중복 합산을 줄여 최적화
from itertools import combinations # itertools 모듈에서 combinations 함수를 불러옴
def solution(numbers):
return sorted(list(set([sum([i, j]) for i, j in combinations(numbers, 2)])))
🟣 combinations(numbers, 2)
- combinations 함수는 주어진 리스트 numbers에서 중복 없이 2개의 요소를 뽑는 모든 가능한 조합을 생성
- 예를 들어, numbers = [2, 1, 3, 4, 1]일 때, 이 함수는 다음과 같은 2개 숫자의 모든 조합을 반환
- (2, 1), (2, 3), (2, 4), (2, 1), (1, 3), (1, 4), (1, 1), (3, 4), (3, 1), (4, 1)
더보기
🔖 combinations 함수
- combinations 함수는 주어진 리스트 또는 다른 iterable에서 순서를 고려하지 않고, 특정 개수의 요소를 뽑는 모든 가능한 조합을 생성
- itertools 모듈에서 불러옴
💭 주요 특징
- 중복이 없음 : 순서를 고려하지 않고, 각 요소를 한 번만 선택
- r개의 요소 선택 : 두 번째 인자인 r은 몇 개의 요소를 선택할지 결정
- 결과는 튜플 : 반환된 각 조합은 튜플 형식
🪄 예시
from itertools import combinations
numbers = [1, 2, 3, 4]
combs = combinations(numbers, 2) # 2개의 요소로 이루어진 조합을 생성
for comb in combs:
print(comb)
출력:
(1, 2)
(1, 3)
(1, 4)
(2, 3)
(2, 4)
(3, 4)
🟣 리스트 컴프리헨션 for i, j in combinations(numbers, 2)
- 위에서 만든 조합 (i, j)에 대해, i와 j의 합을 구하는 리스트 컴프리헨션
[sum([i, j]) for i, j in combinations(numbers, 2)]
- 예를 들어, (2, 1) → 2 + 1 = 3, (2, 3) → 2 + 3 = 5, 이런 식으로 모든 조합에 대해 두 숫자의 합을 계산
- 결과적으로 [3, 5, 6, 3, 4, 5, 2, 7, 4, 5]와 같은 리스트가 생성
🟣 set()으로 중복 제거
- 리스트 컴프리헨션으로 얻은 결과는 [3, 5, 6, 3, 4, 5, 2, 7, 4, 5]인데, 여기에는 중복된 값이 포함되어 있음
- 이를 set()으로 감싸서 중복을 제거
set([3, 5, 6, 3, 4, 5, 2, 7, 4, 5]) # 결과: {2, 3, 4, 5, 6, 7}
🟣 list()로 다시 리스트로 변환
- 집합(set)은 순서가 없으므로, 다시 리스트로 변환
list({2, 3, 4, 5, 6, 7}) # 결과: [2, 3, 4, 5, 6, 7]
🟣 sorted()로 정렬
- 리스트를 오름차순으로 정렬
sorted([2, 3, 4, 5, 6, 7]) # 결과: [2, 3, 4, 5, 6, 7]
🟣 최종 반환
- 정렬된 리스트 [2, 3, 4, 5, 6, 7]을 반환
'📒 Today I Learn > 🐍 Python' 카테고리의 다른 글
[Python] 푸드 파이트 대회 (0) | 2024.09.26 |
---|---|
[Python] 가장 가까운 같은 글자 (0) | 2024.09.25 |
[Python] k번째 수 (0) | 2024.09.19 |
[Python] 문자열 내 마음대로 정렬하기 (0) | 2024.09.13 |
[Python] 숫자 문자열과 영단어 (딕셔너리 이용) (0) | 2024.09.12 |