파이썬 기초 강좌: 9. 딕셔너리 예제와 실습 (Python Basics – Dictionary Examples and Exercises)

파이썬 기초 강좌 9장 딕셔너리 파트입니다. 파이썬의 딕셔너리는 데이터를 키와 값의 쌍으로 저장할 수 있는 강력한 도구입니다. 이 장에서는 딕셔너리를 사용하여 데이터 분석, 텍스트 파싱 등의 작업을 수행하는 방법을 학습합니다. 딕셔너리 생성 및 반복, 파일 처리와 결합한 고급 텍스트 파싱 기법을 다양한 예제와 함께 살펴봅니다. 연습문제를 통해 실습하며 이해를 깊이 있게 다질 수 있습니다. 이를 통해 파이썬 딕셔너리를 활용한 실질적인 데이터 처리 능력을 배양할 수 있습니다.

파이썬 기초 강좌 - 딕셔너리 예제와 실습

0. 파이썬 기초 강좌 – 딕셔너리 소개

파이썬의 딕셔너리는 키(key)와 값(value)을 매핑하는 컬렉션입니다. 리스트와 달리 딕셔너리는 인덱스로 숫자 대신 거의 모든 유형의 데이터를 사용할 수 있습니다. 딕셔너리는 매우 유연하며 다양한 상황에서 유용하게 사용될 수 있습니다.

  • (실습) 딕셔너리 생성하기
eng2sp = dict()
eng2sp['one'] = 'uno'
print(eng2sp)  # 출력: {'one': 'uno'}

이 예제는 ‘one’이라는 영어 단어를 스페인어 ‘uno’로 매핑하는 간단한 딕셔너리를 보여줍니다.

1. 카운터 집합으로서의 딕셔너리

딕셔너리는 요소의 출현 횟수를 세는 데 이상적입니다. 예를 들어, 문자열에서 각 문자가 몇 번 나타나는지 세려면 다음과 같이 작성할 수 있습니다:

word = 'brontosaurus'
d = dict()
for c in word:
    d[c] = d.get(c, 0) + 1
print(d)  # 출력: {'b': 1, 'r': 2, 'o': 2, 'n': 1, 't': 1, 's': 2, 'a': 1, 'u': 2}

여기서 d.get(c, 0)은 키 c가 딕셔너리에 있으면 그 값을 반환하고, 없으면 0을 반환합니다. 이는 처음 등장하는 문자의 경우 값을 0으로 초기화하는 데 유용합니다.

2. 딕셔너리와 파일

딕셔너리를 사용하여 파일에서 단어 출현 횟수를 셀 수 있습니다. 이는 텍스트 분석 작업에 매우 유용합니다.

  • (실습) 파일에서 단어 카운트
fname = input('파일 이름을 입력하세요: ')
try:
    fhand = open(fname)
except:
    print('파일을 열 수 없습니다:', fname)
    exit()

counts = dict()
for line in fhand:
    words = line.split()
    for word in words:
        counts[word] = counts.get(word, 0) + 1

print(counts)

이 프로그램은 파일의 각 줄을 읽고, 줄을 단어로 나눈 후 각 단어의 출현 횟수를 딕셔너리에 저장합니다.

3. 딕셔너리와 반복문

딕셔너리를 반복하여 키와 해당 값을 접근할 수 있습니다.

  • (실습) 딕셔너리 반복하기
counts = {'chuck': 1, 'annie': 42, 'jan': 100}
for key in counts:
    print(key, counts[key])

이 예제에서는 딕셔너리의 각 키와 해당 값을 출력합니다.

4. 고급 텍스트 파싱

더 복잡한 텍스트 파싱을 위해 문자열 메서드인 translatelower를 사용할 수 있습니다. 예를 들어, 구두점을 제거하고 텍스트를 소문자로 변환하여 분석을 쉽게 만들 수 있습니다.

  • (실습#1) 구두점 제거 및 소문자 변환
import string

line = "Hello, world!"
line = line.translate(str.maketrans("", "", string.punctuation))
line = line.lower()
print(line)  # 출력: hello world
  • (실습#2) 텍스트 정리와 단어 카운트
import string

fname = input('파일 이름을 입력하세요: ')
try:
    fhand = open(fname)
except:
    print('파일을 열 수 없습니다:', fname)
    exit()

counts = dict()
for line in fhand:
    line = line.rstrip()
    line = line.translate(str.maketrans("", "", string.punctuation))
    line = line.lower()
    words = line.split()
    for word in words:
        counts[word] = counts.get(word, 0) + 1

print(counts)

이 프로그램은 파일의 각 줄을 읽고 구두점을 제거하고 소문자로 변환한 후 단어를 나누어 딕셔너리에 저장합니다.

Exercises

(1) 단어 조회 프로그램

  • 다음 링크에서 파일 www.py4e.com/code3/words.txt 를 다운로드하세요.
  • 이 파일의 단어들을 읽어서 딕셔너리의 키로 저장하는 프로그램을 작성하세요.
  • 사용자로 부터 단어를 입력받고 in 연산자를 사용하여 문자열이 딕셔너리에 있는지 확인하는 기능을 제공하세요.
  • (정답)
# 파일 이름을 입력 받습니다.
fname = input('Enter the file name: ')
try:
    # 파일을 엽니다.
    fhand = open(fname)
except:
    print('File cannot be opened:', fname)
    exit()

# 빈 딕셔너리를 만듭니다.
words_dict = dict()

# 파일의 각 줄을 읽습니다.
for line in fhand:
    # 각 줄을 단어로 나눕니다.
    words = line.split()
    # 각 단어를 딕셔너리의 키로 저장합니다.
    for word in words:
        words_dict[word] = None

# 딕셔너리에 특정 단어가 있는지 확인합니다.
word_to_check = input('Enter a word to check: ')
if word_to_check in words_dict:
    print(f'The word "{word_to_check}" is in the dictionary.')
else:
    print(f'The word "{word_to_check}" is not in the dictionary.')

(2) 요일 분류 프로그램

  • 각 메일 메시지를 요일별로 분류하는 프로그램을 작성하세요.
  • 이를 위해 “From”으로 시작하는 줄을 찾아, 세 번째 단어를 확인하여 각 요일의 출현 횟수를 누적해서 세어야 합니다.
  • 프로그램이 끝나면 딕셔너리의 내용을 출력하세요 (순서는 중요하지 않습니다).
  • Sample Line
From stephen.marquard@uct.ac.za Sat Jan 5 09:14:16 2008
  • Sample 실행
python dow.py
Enter a file name: mbox-short.txt
{'Fri': 20, 'Thu': 6, 'Sat': 1}
  • (정답)
# 파일 이름을 입력 받습니다.
fname = input('Enter a file name: ')
try:
    # 파일을 엽니다.
    fhand = open(fname)
except:
    print('File cannot be opened:', fname)
    exit()

# 빈 딕셔너리를 만듭니다.
days_count = dict()

# 파일의 각 줄을 읽습니다.
for line in fhand:
    # "From"으로 시작하는 줄을 찾습니다.
    if line.startswith('From '):
        words = line.split()
        # 세 번째 단어를 가져와 요일로 간주하고, 출현 횟수를 누적합니다.
        day = words[2]
        days_count[day] = days_count.get(day, 0) + 1

# 딕셔너리의 내용을 출력합니다.
print(days_count)

(3) 이메일 주소 카운터

  • 메일 로그를 읽고, 각 이메일 주소에서 몇 개의 메시지가 왔는지 세는 히스토그램을 딕셔너리를 사용하여 작성하고,
  • 그 딕셔너리를 출력하는 프로그램을 작성하세요.
  • Sample 실행
Enter file name: mbox-short.txt
{'gopal.ramasammycook@gmail.com': 1, 'louis@media.berkeley.edu': 3,
'cwen@iupui.edu': 5, 'antranig@caret.cam.ac.uk': 1,
'rjlowe@iupui.edu': 2, 'gsilver@umich.edu': 3,
'david.horwitz@uct.ac.za': 4, 'wagnermr@iupui.edu': 1,
'zqian@umich.edu': 4, 'stephen.marquard@uct.ac.za': 2,
'ray@media.berkeley.edu': 1}
  • (정답)
# 파일 이름을 입력 받습니다.
fname = input('Enter file name: ')
try:
    # 파일을 엽니다.
    fhand = open(fname)
except:
    print('File cannot be opened:', fname)
    exit()

# 빈 딕셔너리를 만듭니다.
email_count = dict()

# 파일의 각 줄을 읽습니다.
for line in fhand:
    # "From "으로 시작하는 줄을 찾습니다.
    if line.startswith('From '):
        words = line.split()
        # 이메일 주소를 가져와 딕셔너리에 출현 횟수를 누적합니다.
        email = words[1]
        email_count[email] = email_count.get(email, 0) + 1

# 딕셔너리의 내용을 출력합니다.
print(email_count)

(4) 이메일 주소 카운터 + 최대/최소

  • 위의 3번 프로그램에 코드를 추가하여 파일에서 가장 많은 메시지를 보낸 사람이 누구인지 알아내는 프로그램을 작성하세요.
  • 모든 데이터를 읽고 딕셔너리가 생성된 후, 최대 루프(5장: 최대값과 최소값 루프 참고)를 사용하여 가장 많은 메시지를 보낸 사람을 찾아 몇 개의 메시지를 보냈는지 출력하세요.
  • Sample 실행
Enter a file name: mbox-short.txt
cwen@iupui.edu 5

Enter a file name: mbox.txt
zqian@umich.edu 195
  • (정답)
# 파일 이름을 입력 받습니다.
fname = input('Enter file name: ')
try:
    # 파일을 엽니다.
    fhand = open(fname)
except:
    print('File cannot be opened:', fname)
    exit()

# 빈 딕셔너리를 만듭니다.
email_count = dict()

# 파일의 각 줄을 읽습니다.
for line in fhand:
    # "From "으로 시작하는 줄을 찾습니다.
    if line.startswith('From '):
        words = line.split()
        # 이메일 주소를 가져와 딕셔너리에 출현 횟수를 누적합니다.
        email = words[1]
        email_count[email] = email_count.get(email, 0) + 1

# 가장 많은 메시지를 보낸 사람을 찾습니다.
max_emails = None
max_count = None
for email, count in email_count.items():
    if max_count is None or count > max_count:
        max_emails = email
        max_count = count

# 가장 많은 메시지를 보낸 사람과 그 횟수를 출력합니다.
print(max_emails, max_count)

(5) 도메인 카운터

  • 이 프로그램은 메일이 온 주소 대신 도메인 이름을 기록합니다.
  • 프로그램이 끝나면 딕셔너리의 내용을 출력하세요.
  • Sample 실행
python schoolcount.py
Enter a file name: mbox-short.txt
{'media.berkeley.edu': 4, 'uct.ac.za': 6, 'umich.edu': 7,
'gmail.com': 1, 'caret.cam.ac.uk': 1, 'iupui.edu': 8}
  • (정답)
# 파일 이름을 입력 받습니다.
fname = input('Enter file name: ')
try:
    # 파일을 엽니다.
    fhand = open(fname)
except:
    print('File cannot be opened:', fname)
    exit()

# 빈 딕셔너리를 만듭니다.
domain_count = dict()

# 파일의 각 줄을 읽습니다.
for line in fhand:
    # "From "으로 시작하는 줄을 찾습니다.
    if line.startswith('From '):
        words = line.split()
        # 이메일 주소에서 도메인을 추출합니다.
        email = words[1]
        domain = email.split('@')[1]
        # 도메인의 출현 횟수를 딕셔너리에 누적합니다.
        domain_count[domain] = domain_count.get(domain, 0) + 1

# 딕셔너리의 내용을 출력합니다.
print(domain_count)

파이썬 기초 강좌: 8. 리스트 예제와 실습 (Python Basics – List Examples and Exercises)

파이썬 기초 강좌: 10. 튜플 예제와 실습 (Python Basics – Tuple Examples and Exercises)

Leave a Comment