99클럽 코테 스터디 10일차 TIL + collections, defaultdict()

임정민·2025년 1월 24일
0
post-thumbnail

1. 문제 설명

[문제 내용]

노교수는 지금까지 서울사이버대학교 빅데이터·정보보호학과와 인공지능학과, 컴퓨터공학과 등에서 NN개의 수업을 진행하였다. 수업을 들었던 학생들을 회상하던 어느 날, 노교수는 자신의 수업을 MM개 이상 들은 학생이 몇 명인지 궁금해졌다.

수업과 학생의 수가 너무 많아 한눈에 들어오지 않았던 노교수는, 당신에게 분석을 의뢰했다. 각 수업을 들은 학생들의 학번이 주어질 때, 조건을 만족하는 학생의 수를 구하자.

[입력]

첫 번째 줄에 NN, MM이 차례대로 주어진다. (1N100;(1 \le N \le 100; 1MN)1 \le M \le N)

두 번째 줄부터 2×N2 \times N개의 줄에 걸쳐 각 수업에 대한 정보 NN개가 순서대로 주어진다.

ii번 수업의 정보는 두 개의 줄로 이뤄진다. 첫 번째 줄에 과목의 수강생 수 KiK_i, 두 번째 줄에 ii번 수업을 들은 학생들의 학번 KiK_i개가 공백 하나로 구분되어 주어진다. (1Ki240)(1 \le K_i \le 240)

학번은 숫자 8개로 구성되며, 항상 11로 시작한다. 한 수업에 동일한 사람이 중복되어 있는 경우는 주어지지 않는다.

[출력]

첫 번째 줄에 MM개 이상의 수업을 들은 학생의 수를 출력한다.

[입출력 예]

[노트]

서울사이버대학교에서 한 반의 학생수는 최대 240240명이고, 학부생의 학번은 11로 시작한다.

2. 풀이

from collections import defaultdict

N, M = map(int, input().split())

student_counts = defaultdict(int)

for _ in range(N):
    K_i = int(input()) 
    student_ids = list(map(int, input().split()))
    
    for student_id in student_ids:
        student_counts[student_id] += 1

result = sum(1 for count in student_counts.values() if count >= M)

print(result)

3. 회고

3-1. 문제 풀이 과정

이번 문제 풀면서 느낀 건 대략적으로 어떻게 접근해야 할 지는 잘 알고 있는데, 어떤 기능을 통해서 풀어야 하는지를 잘 모르는 것 같았다.

딕셔너리 이용해서 받아오면 되는데.. 그래서 어떤 함수를 써야하는지? 계속 이 과정만 반복하다 답답해서 풀이를 조금 더 상세하게 써보기로 했다.

먼저 N과 M을 받아온다. 그 다음 줄에서는 2 × N 줄에서 각 수업의 학생 수와 해당 학번 목록을 읽어온다고 했다.

N, M = map(int, input().split())

각 수업의 학생 수와 해당 학번을 sys.stdin.readline()을 통해 입력 받아야하나? 그러면 각 라인을 기준으로 키와 값을 저장하려면 어떻게 해야하지? 이렇게 고민만 하다가 찾은게 defaultdict였다.

student_counts = defaultdict(int)

for _ in range(N):
    K_i = int(input())
    student_ids = list(map(int, input().split()))
    
    for student_id in student_ids:
        student_counts[student_id] += 1

새롭게 알게된 내용에 적을 예정이지만 괄호 안의 형태로 딕셔너리를 초기화한다고 한다. 수업 개수 N 만큼 수업을 들은 학생 수와 그 학생들의 학번 리스트를 입력 받는다.

그리고 student_ids에는 20240001과 같은 학번들이 들어있을 것이고 그 학생들이 수강 중인 수업을 세어야 하니까 student_counts[student_id] += 1 형태로 작성한다.

특히 이 부분이 이해가 잘 안 되었는데 리스트 형태로 저장되어 있는 각 학번들에게 count 값을 준다고 생각하면 되는 것 같다. 우리가 자주 쓰는 count += 1을 떠올려 보자.

result = sum(1 for count in student_counts.values() if count >= M)

모든 학생들의 수강 횟수 중에서 M개 이상 수업을 들은 학생의 수만 세어야 하므로, 만족하는 학생들에게 1을 부여하고 sum()을 통해 더하여 result를 출력하면 된다.

count = 0
for value in student_counts.values():
    if value >= M:
        count += 1
print(count)

간결한 코드라 이해가 잘 안 되었는데, 풀어서 보면 이해가 잘 된다!

3-2. 새롭게 배운 내용

  • collections : Python에서 데이터 구조와 관련된 고급 자료형을 제공한다. list, dict, set, tuple을 보완할 수 있다.

  • defaultdict() : 딕셔너리와 유사하지만 존재하지 않는 키에 접근할 때 기본값을 자동으로 설정한다. int로 설정하면 기본 값이 0이 되고, list로 설정하면 기본 값은 리스트 형태가 된다. 특정 키에 값을 누적하거나 갱신할 때 유용하다.

from collections import defaultdict

# 기본값이 0인 defaultdict 생성
dd = defaultdict(int)
dd['a'] += 1
dd['b'] += 2

print(dd)  # defaultdict(<class 'int'>, {'a': 1, 'b': 2})
print(dd['c'])  # 0 (자동으로 기본값 0 생성)
# 일반 딕셔너리
d = {}
# print(d['missing'])  # KeyError: 'missing'

# defaultdict
dd = defaultdict(int)
print(dd['missing'])  # 0
profile
Data Science and Natural Language Processing

0개의 댓글

관련 채용 정보