Chapter 01

파이썬이란 무엇인가?

1.1 파이썬의 정의

파이썬(Python)은 1991년 네덜란드의 프로그래머 귀도 반 로섬(Guido van Rossum)이 만든 범용 프로그래밍 언어입니다. "사람이 읽기 쉬운 코드"를 철학으로 설계되어, 다른 언어에 비해 문법이 직관적이고 간결합니다. 이름은 영국의 코미디 그룹 '몬티 파이썬'에서 따왔습니다.

파이썬은 현재 전 세계에서 가장 인기 있는 프로그래밍 언어 중 하나입니다. 웹 개발, 데이터 과학, 인공지능, 자동화, 게임, 과학 계산 등 거의 모든 분야에서 활용됩니다. 특히 최근 AI/머신러닝 붐과 함께 파이썬의 인기는 폭발적으로 성장했습니다.

1.2 왜 파이썬인가?

프로그래밍 입문자가 파이썬을 선택하면 좋은 이유는 다양합니다.

  • 쉬운 문법 : 영어 문장처럼 읽히는 코드를 작성할 수 있어, 처음 배우는 사람도 빠르게 이해할 수 있습니다.
  • 강력한 생태계 : 30만 개 이상의 라이브러리(패키지)가 있어, "바퀴를 다시 발명"할 필요가 없습니다.
  • 거대한 커뮤니티 : 전 세계 수백만 개발자가 사용하므로, 문제가 생기면 검색으로 쉽게 해결할 수 있습니다.
  • 다양한 활용 분야 : 웹, 데이터, AI, 자동화, IoT, 게임 등 거의 모든 IT 분야를 커버합니다.
  • 높은 취업 수요 : 대부분의 IT 기업에서 파이썬 개발자를 찾고 있으며, 비개발 직군에서도 데이터 분석 등에 파이썬을 활용합니다.

1.3 파이썬의 특징

특징설명
인터프리터 언어코드를 한 줄씩 해석하며 실행합니다. 컴파일 과정이 필요 없어 빠르게 테스트할 수 있습니다.
동적 타이핑변수의 타입을 미리 선언하지 않아도 됩니다. 파이썬이 알아서 판단합니다.
들여쓰기 기반중괄호({}) 대신 들여쓰기(Indentation)로 코드 블록을 구분합니다.
멀티 패러다임절차적, 객체지향, 함수형 프로그래밍을 모두 지원합니다.
크로스 플랫폼Windows, macOS, Linux 등 거의 모든 운영체제에서 동일하게 실행됩니다.
풍부한 표준 라이브러리"Batteries Included" 철학. 설치만 하면 수많은 기능을 바로 사용할 수 있습니다.

1.4 파이썬의 활용 분야

분야대표 라이브러리 / 프레임워크예시
웹 개발Django, Flask, FastAPI인스타그램, 핀터레스트 등
데이터 과학Pandas, NumPy, Matplotlib데이터 분석, 시각화
인공지능 / 머신러닝TensorFlow, PyTorch, scikit-learn이미지 인식, 자연어 처리
자동화 / 스크립팅Selenium, BeautifulSoup, os웹 크롤링, 업무 자동화
게임 개발Pygame2D 게임, 프로토타이핑
임베디드 / IoTMicroPython, CircuitPython라즈베리 파이, 센서 제어
Tip! 이 튜토리얼은 Python 3.10 이상을 기준으로 작성되었습니다. Python 2는 2020년 1월에 공식 지원이 종료되었으므로, 반드시 Python 3를 사용하세요.
Chapter 02

실습 환경 설정

2.1 파이썬 설치

파이썬을 사용하려면 먼저 컴퓨터에 파이썬 인터프리터를 설치해야 합니다. 공식 사이트 python.org에서 운영체제에 맞는 설치 파일을 다운로드할 수 있습니다.

Windows 설치

python.org에서 Windows용 설치 파일을 다운로드합니다. 설치 시 반드시 "Add Python to PATH" 옵션을 체크해야 합니다. 이 옵션을 빠뜨리면 명령 프롬프트에서 python 명령어를 찾을 수 없게 됩니다.

Windows CMD
# 설치 확인
python --version
# 출력 예: Python 3.12.1

# pip (패키지 관리자) 확인
pip --version

macOS 설치

macOS에는 Python 2가 기본 설치되어 있을 수 있지만, 우리는 Python 3를 사용합니다. Homebrew를 이용한 설치가 가장 편리합니다.

macOS Terminal
# Homebrew 설치 (이미 있다면 생략)
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

# Python 3 설치
brew install python

# 확인
python3 --version

Linux (Ubuntu/Debian) 설치

Linux Terminal
sudo apt update
sudo apt install python3 python3-pip python3-venv

# 확인
python3 --version

2.2 온라인 실습 환경 (설치 불필요)

설치 없이 바로 파이썬을 실행해 보고 싶다면, 브라우저에서 사용할 수 있는 온라인 환경을 추천합니다.

  • Google Colab (colab.research.google.com) : 무료 GPU/TPU 제공, 데이터 과학에 최적
  • Replit (replit.com) : 브라우저에서 바로 코드 작성 및 실행
  • Python Online (python.org/shell) : 파이썬 공식 온라인 셸

2.3 코드 에디터 & IDE

코드를 효율적으로 작성하려면 좋은 편집 도구가 필요합니다. 대표적인 추천 도구를 소개합니다.

도구유형특징추천 대상
VS Code에디터무료, 가볍고 강력한 확장 생태계모든 개발자 (가장 추천)
PyCharmIDE파이썬 전용, 디버깅/리팩토링 강력전문 파이썬 개발자
Jupyter Notebook노트북코드+결과+설명 혼합, 셀 단위 실행데이터 과학, 교육
IDLEIDE파이썬 기본 내장, 초경량처음 시작하는 입문자

2.4 VS Code + Python 확장 설치

이 튜토리얼에서는 VS Code를 기본 에디터로 사용하는 것을 권장합니다.

  1. code.visualstudio.com에서 VS Code를 다운로드·설치합니다.
  2. VS Code를 실행하고, 왼쪽 사이드바의 확장(Extensions) 아이콘을 클릭합니다.
  3. "Python"을 검색하여 Microsoft의 Python 확장을 설치합니다.
  4. 새 파일을 만들고 hello.py로 저장한 뒤, 코드를 작성합니다.
참고 : VS Code에서 파이썬 파일을 실행하려면 터미널(Ctrl + `)을 열고 python hello.py를 입력하거나, 우측 상단의 ▷ 실행 버튼을 클릭하면 됩니다.
Chapter 03

첫 번째 프로그램: Hello, World!

3.1 Hello, World! 출력하기

거의 모든 프로그래밍 학습은 "Hello, World!"를 출력하는 것에서 시작됩니다. 파이썬에서는 단 한 줄이면 됩니다.

Python
print("Hello, World!")
실행 결과
Hello, World!

print()는 파이썬에서 가장 기본적인 출력 함수입니다. 괄호 안에 넣은 값을 화면에 표시합니다. 큰따옴표(") 또는 작은따옴표(')로 감싼 텍스트를 문자열(String)이라고 합니다.

3.2 print() 함수 다양하게 사용하기

Python
# 작은따옴표도 동일하게 동작합니다
print('안녕하세요, 파이썬!')

# 여러 값을 쉼표로 구분하면 공백으로 연결됩니다
print("나이:", 25, "살")

# sep 인자로 구분자를 변경할 수 있습니다
print("2024", "01", "15", sep="-")

# end 인자로 줄바꿈 대신 다른 문자를 지정합니다
print("Hello", end=" ")
print("World")

# 빈 줄 출력
print()
실행 결과
안녕하세요, 파이썬! 나이: 25 살 2024-01-15 Hello World

3.3 주석(Comment) 작성하기

주석은 코드 실행에 영향을 주지 않는 설명 메모입니다. 미래의 나 자신, 또는 다른 개발자가 코드를 이해하는 데 큰 도움이 됩니다. 좋은 주석은 "왜(Why)" 이런 코드를 작성했는지를 설명합니다.

Python
# 한 줄 주석: 샵(#) 뒤에 작성합니다
print("실행됩니다")  # 코드 끝에도 주석을 달 수 있습니다

# 여러 줄 주석: 각 줄 앞에 #를 붙입니다
# 이 코드는 인사말을 출력하는 프로그램입니다.
# 작성자: 홍길동
# 작성일: 2024-01-15

"""
큰따옴표 세 개로 감싸면 여러 줄 문자열(docstring)입니다.
이것도 주석처럼 사용되기도 합니다.
주로 함수나 클래스의 설명에 사용됩니다.
"""

3.4 input() 함수로 입력 받기

input() 함수는 사용자로부터 키보드 입력을 받습니다. 입력받은 값은 항상 문자열(str) 타입입니다.

Python
# 이름을 입력받아 인사하기
name = input("이름을 입력하세요: ")
print("안녕하세요,", name, "님!")

# 나이를 입력받아 출력하기 (숫자로 변환)
age = int(input("나이를 입력하세요: "))
print("내년에는", age + 1, "살이 됩니다!")
실행 결과 (입력: 홍길동, 25)
이름을 입력하세요: 홍길동 안녕하세요, 홍길동 님! 나이를 입력하세요: 25 내년에는 26 살이 됩니다!
주의! input()은 항상 문자열을 반환합니다. 숫자 계산을 하려면 int()float()로 변환해야 합니다. 변환할 수 없는 값을 입력하면 에러(ValueError)가 발생합니다.
Chapter 04

변수와 데이터 타입

4.1 변수(Variable)란?

변수는 값을 저장하는 이름표가 붙은 상자와 같습니다. 파이썬에서는 =(할당 연산자)를 사용하여 값을 변수에 저장합니다. C나 Java와 달리 타입을 미리 선언할 필요가 없습니다. 파이썬이 값을 보고 자동으로 타입을 결정합니다.

Python
# 변수에 값 할당하기
name = "김민수"          # 문자열(str)
age = 25                  # 정수(int)
height = 175.5            # 실수(float)
is_student = True         # 불리언(bool)

# 변수 값 출력
print(name)      # 김민수
print(age)       # 25
print(height)    # 175.5

# 변수 값 변경 (재할당)
age = 26
print(age)       # 26

# 여러 변수에 동시에 값 할당
x, y, z = 1, 2, 3
a = b = c = 0

4.2 변수 이름 규칙

변수 이름을 지을 때 반드시 따라야 하는 규칙이 있습니다. 좋은 변수 이름은 코드의 가독성을 크게 향상시킵니다.

규칙올바른 예잘못된 예
문자, 숫자, 밑줄(_)만 사용 가능user_name, age2user-name, age!
숫자로 시작할 수 없음item1, _temp1item, 2nd_place
예약어(키워드) 사용 불가my_class, is_trueclass, True, for
대소문자 구분Name과 name은 다른 변수-
관례: snake_case 사용user_name, total_priceuserName (PEP 8 비권장)

4.3 기본 데이터 타입

파이썬의 핵심 데이터 타입은 크게 네 가지입니다. type() 함수로 변수의 타입을 확인할 수 있습니다.

Python
# 정수 (int) - 소수점 없는 숫자
age = 25
print(type(age))          # <class 'int'>

# 실수 (float) - 소수점 있는 숫자
price = 19900.50
print(type(price))        # <class 'float'>

# 문자열 (str) - 텍스트 데이터
greeting = "안녕하세요"
print(type(greeting))     # <class 'str'>

# 불리언 (bool) - 참(True) 또는 거짓(False)
is_active = True
print(type(is_active))    # <class 'bool'>

# None - 값이 없음을 나타내는 특수 타입
result = None
print(type(result))       # <class 'NoneType'>

4.4 타입 변환 (Type Casting)

한 데이터 타입을 다른 타입으로 변환하는 것을 타입 변환이라고 합니다. 서로 다른 타입의 데이터를 연산하거나, 사용자 입력(항상 str)을 숫자로 바꿀 때 자주 사용합니다.

Python
# 문자열 → 정수
num_str = "42"
num_int = int(num_str)
print(num_int + 8)           # 50

# 문자열 → 실수
pi_str = "3.14"
pi_float = float(pi_str)
print(pi_float)               # 3.14

# 숫자 → 문자열
age = 25
age_str = str(age)
print("나이: " + age_str)      # 나이: 25

# 정수 ↔ 실수
print(float(10))              # 10.0
print(int(3.99))             # 3 (소수점 버림, 반올림 아님!)

# 불리언 변환
print(bool(0))               # False
print(bool(1))               # True
print(bool(""))              # False (빈 문자열)
print(bool("hello"))         # True (비어있지 않으면 True)
파이썬의 Falsy 값들 : bool()로 변환했을 때 False가 되는 값들이 있습니다. 0, 0.0, ""(빈 문자열), [](빈 리스트), {}(빈 딕셔너리), None, False 자체가 이에 해당합니다. 그 외의 값은 모두 True입니다.
Chapter 05

숫자와 연산자

5.1 산술 연산자

파이썬은 기본적인 사칙연산은 물론, 거듭제곱, 정수 나눗셈, 나머지 연산 등 다양한 산술 연산자를 제공합니다.

연산자의미예시결과
+더하기10 + 313
-빼기10 - 37
*곱하기10 * 330
/나누기 (실수)10 / 33.3333...
//정수 나눗셈 (몫)10 // 33
%나머지10 % 31
**거듭제곱2 ** 101024
Python
# 기본 산술 연산
print(10 + 3)     # 13
print(10 - 3)     # 7
print(10 * 3)     # 30
print(10 / 3)     # 3.3333333333333335
print(10 // 3)    # 3  (소수점 버림)
print(10 % 3)     # 1  (나머지)
print(2 ** 10)    # 1024 (2의 10승)

# 실전 활용: 시간 변환
total_minutes = 135
hours = total_minutes // 60     # 2시간
minutes = total_minutes % 60    # 15분
print(f"{total_minutes}분 = {hours}시간 {minutes}분")
# 135분 = 2시간 15분

5.2 복합 대입 연산자

변수의 값을 변경할 때, 연산과 대입을 한 번에 수행할 수 있습니다.

Python
score = 100

score += 10    # score = score + 10  → 110
score -= 20    # score = score - 20  → 90
score *= 2     # score = score * 2   → 180
score //= 3    # score = score // 3  → 60
score %= 7     # score = score % 7   → 4
score **= 3    # score = score ** 3  → 64

print(score)   # 64

5.3 비교 연산자

두 값을 비교하며, 결과는 항상 True 또는 False입니다. 조건문(if)에서 핵심적으로 사용됩니다.

Python
x = 10
y = 20

print(x == y)    # False (같다)
print(x != y)    # True  (같지 않다)
print(x > y)     # False (크다)
print(x < y)     # True  (작다)
print(x >= 10)   # True  (크거나 같다)
print(x <= 5)    # False (작거나 같다)

# 파이썬만의 특별한 연쇄 비교
age = 25
print(18 <= age <= 65)   # True (다른 언어에서는 불가)

5.4 논리 연산자

Python
age = 25
has_id = True

# and : 둘 다 True일 때 True
print(age >= 18 and has_id)     # True

# or : 하나라도 True이면 True
print(age < 18 or has_id)       # True

# not : 반대로 뒤집기
print(not has_id)                # False

# 복합 조건
score = 85
grade = "A"
print(score >= 80 and grade == "A")   # True
Tip! 파이썬의 정수는 크기 제한이 없습니다! C언어나 Java에서는 정수가 일정 크기를 넘으면 오버플로우가 발생하지만, 파이썬은 2 ** 1000처럼 아무리 큰 수도 정확하게 계산합니다.
Chapter 06

문자열(String) 다루기

6.1 문자열 생성

문자열은 파이썬에서 가장 자주 다루는 데이터 타입 중 하나입니다. 텍스트 데이터를 처리하는 다양한 방법을 익혀두면 실무에서 큰 도움이 됩니다.

Python
# 작은따옴표와 큰따옴표 모두 가능
s1 = 'Hello'
s2 = "World"

# 따옴표 안에 따옴표가 필요할 때
s3 = "It's a beautiful day"     # 큰따옴표로 감싸기
s4 = 'He said "Hello"'           # 작은따옴표로 감싸기
s5 = 'It\'s a beautiful day'     # 이스케이프 문자 사용

# 여러 줄 문자열 (삼중 따옴표)
poem = """첫 번째 줄
두 번째 줄
세 번째 줄"""
print(poem)

6.2 문자열 인덱싱과 슬라이싱

문자열의 각 글자에는 번호(인덱스)가 매겨져 있습니다. 파이썬의 인덱스는 0부터 시작합니다. 음수 인덱스를 사용하면 뒤에서부터 셀 수 있습니다.

Python
text = "Python"
#        P  y  t  h  o  n
# 인덱스: 0  1  2  3  4  5
# 음수: -6 -5 -4 -3 -2 -1

# 인덱싱: 특정 위치의 글자 하나
print(text[0])     # P (첫 번째 글자)
print(text[5])     # n (마지막 글자)
print(text[-1])    # n (뒤에서 첫 번째)
print(text[-2])    # o (뒤에서 두 번째)

# 슬라이싱: [시작:끝] (끝 인덱스는 포함 안 됨!)
print(text[0:3])   # Pyt (0, 1, 2번)
print(text[2:])    # thon (2번부터 끝까지)
print(text[:4])    # Pyth (처음부터 3번까지)
print(text[::2])   # Pto (2칸씩 건너뛰기)
print(text[::-1])  # nohtyP (뒤집기!)

6.3 문자열 메서드

파이썬의 문자열은 수십 가지의 편리한 메서드를 제공합니다. 문자열은 불변(immutable) 객체이므로, 메서드를 호출해도 원본이 바뀌지 않고 새로운 문자열이 반환됩니다.

Python
msg = "  Hello, Python World!  "

# 대소문자 변환
print(msg.upper())            # "  HELLO, PYTHON WORLD!  "
print(msg.lower())            # "  hello, python world!  "
print(msg.title())            # "  Hello, Python World!  "

# 공백 제거
print(msg.strip())            # "Hello, Python World!"
print(msg.lstrip())           # "Hello, Python World!  "
print(msg.rstrip())           # "  Hello, Python World!"

# 치환
print(msg.replace("Python", "Java"))
# "  Hello, Java World!  "

# 분리와 결합
fruits = "사과,바나나,포도,딸기"
fruit_list = fruits.split(",")
print(fruit_list)             # ['사과', '바나나', '포도', '딸기']

print(" / ".join(fruit_list))
# "사과 / 바나나 / 포도 / 딸기"

# 검색
print(msg.find("Python"))     # 9 (시작 위치)
print(msg.find("Java"))       # -1 (못 찾으면 -1)
print(msg.count("l"))         # 2
print(msg.startswith("  He")) # True
print(msg.endswith("!  "))    # True

# 검증
print("12345".isdigit())      # True (숫자로만 구성?)
print("hello".isalpha())      # True (문자로만 구성?)
print("abc123".isalnum())     # True (문자+숫자?)

6.4 이스케이프 문자

이스케이프의미예시
\n줄바꿈"첫줄\n둘째줄"
\t"이름\t나이"
\\역슬래시"C:\\Users"
\'작은따옴표'It\'s'
\"큰따옴표"He said \"Hi\""
Tip! 파일 경로처럼 역슬래시가 많은 문자열에는 raw string을 사용하세요. 문자열 앞에 r을 붙이면 이스케이프가 적용되지 않습니다: r"C:\Users\name"
Chapter 07

리스트(List) - 파이썬의 만능 컬렉션

7.1 리스트란?

리스트(List)는 여러 값을 순서대로 담는 컬렉션입니다. 대괄호 []로 만들며, 서로 다른 타입의 값도 함께 넣을 수 있습니다. 파이썬에서 가장 많이 사용되는 자료구조이므로, 반드시 완벽하게 익혀야 합니다.

Python
# 리스트 생성
fruits = ["사과", "바나나", "포도", "딸기"]
numbers = [1, 2, 3, 4, 5]
mixed = ["hello", 42, 3.14, True, None]
empty = []

# 인덱싱 (문자열과 동일한 방식)
print(fruits[0])     # 사과
print(fruits[-1])    # 딸기

# 슬라이싱
print(fruits[1:3])   # ['바나나', '포도']

# 길이 확인
print(len(fruits))   # 4

7.2 리스트 수정하기

문자열과 달리 리스트는 변경 가능(mutable)합니다. 값을 추가, 삭제, 변경할 수 있습니다.

Python
colors = ["빨강", "파랑", "노랑"]

# 값 변경
colors[1] = "초록"
print(colors)    # ['빨강', '초록', '노랑']

# 추가
colors.append("보라")           # 끝에 추가
colors.insert(1, "주황")        # 특정 위치에 삽입
colors.extend(["검정", "흰색"])  # 여러 개 한번에 추가
print(colors)
# ['빨강', '주황', '초록', '노랑', '보라', '검정', '흰색']

# 삭제
colors.remove("초록")            # 값으로 삭제
popped = colors.pop()            # 마지막 요소 꺼내기 (반환+삭제)
print(popped)                    # 흰색
popped2 = colors.pop(0)          # 특정 위치 요소 꺼내기
print(popped2)                   # 빨강
del colors[0]                    # 인덱스로 삭제 (반환 없음)

# 전체 비우기
colors.clear()
print(colors)    # []

7.3 리스트 정렬과 검색

Python
scores = [85, 92, 78, 96, 64, 88]

# 정렬 (원본 변경)
scores.sort()                    # 오름차순
print(scores)    # [64, 78, 85, 88, 92, 96]

scores.sort(reverse=True)       # 내림차순
print(scores)    # [96, 92, 88, 85, 78, 64]

# 정렬 (원본 유지, 새 리스트 반환)
original = [3, 1, 4, 1, 5]
sorted_list = sorted(original)
print(original)     # [3, 1, 4, 1, 5] (원본 유지)
print(sorted_list)  # [1, 1, 3, 4, 5] (새 리스트)

# 검색
print(88 in scores)     # True  (포함 여부)
print(100 in scores)    # False
print(scores.index(88)) # 2 (위치 찾기)
print(scores.count(88)) # 1 (등장 횟수)

# 뒤집기
scores.reverse()
print(scores)    # [64, 78, 85, 88, 92, 96]

7.4 리스트 연산

Python
# 리스트 합치기
a = [1, 2, 3]
b = [4, 5, 6]
print(a + b)        # [1, 2, 3, 4, 5, 6]

# 리스트 반복
print(a * 3)        # [1, 2, 3, 1, 2, 3, 1, 2, 3]

# 중첩 리스트 (2차원)
matrix = [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9]
]
print(matrix[1][2])  # 6 (2행 3열)

# 리스트 복사 (주의!)
original = [1, 2, 3]
shallow = original         # 같은 객체를 가리킴 (복사 아님!)
deep = original.copy()     # 진짜 복사 (새 객체 생성)
deep2 = original[:]        # 슬라이싱으로도 복사 가능
주의! b = a는 리스트를 복사하는 것이 아니라, 같은 리스트를 가리키는 별명을 만드는 것입니다. b를 수정하면 a도 바뀝니다! 진짜 복사를 하려면 a.copy() 또는 a[:]를 사용하세요.
Chapter 08

튜플(Tuple)과 집합(Set)

8.1 튜플(Tuple) - 변경 불가 리스트

튜플은 리스트와 비슷하지만, 한 번 만들면 값을 변경할 수 없습니다(immutable). 소괄호 ()로 만들며, 변하면 안 되는 데이터를 보호할 때 사용합니다. 좌표, RGB 색상값, 함수의 여러 반환값 등이 대표적입니다.

Python
# 튜플 생성
point = (3, 5)
colors = ("빨강", "초록", "파랑")
single = (42,)    # 요소가 하나일 때 반드시 쉼표 필요!

# 인덱싱, 슬라이싱은 리스트와 동일
print(colors[0])     # 빨강
print(colors[1:])    # ('초록', '파랑')

# 값 변경 시도 → 에러!
# colors[0] = "노랑"   # TypeError 발생!

# 언패킹 (여러 변수에 한번에 할당)
x, y = point
print(f"x={x}, y={y}")  # x=3, y=5

# 함수에서 여러 값 반환 시 튜플 활용
def min_max(numbers):
    return min(numbers), max(numbers)

lo, hi = min_max([3, 7, 1, 9, 2])
print(f"최소: {lo}, 최대: {hi}")  # 최소: 1, 최대: 9

8.2 집합(Set) - 중복 없는 컬렉션

집합(Set)은 중복을 허용하지 않고, 순서가 없는 컬렉션입니다. 중괄호 {}로 만듭니다. 수학의 집합 연산(합집합, 교집합, 차집합)을 그대로 지원합니다.

Python
# 집합 생성 - 중복 자동 제거!
numbers = {1, 2, 3, 2, 1, 4}
print(numbers)       # {1, 2, 3, 4} (중복 제거됨)

# 리스트에서 중복 제거하는 가장 쉬운 방법!
names = ["김", "이", "박", "김", "이"]
unique_names = list(set(names))
print(unique_names)  # ['김', '이', '박'] (순서 변경 가능)

# 집합 연산
a = {1, 2, 3, 4}
b = {3, 4, 5, 6}

print(a | b)    # {1, 2, 3, 4, 5, 6}  합집합
print(a & b)    # {3, 4}              교집합
print(a - b)    # {1, 2}              차집합 (a에만 있는 것)
print(a ^ b)    # {1, 2, 5, 6}        대칭차집합

# 추가 / 삭제
a.add(10)
a.discard(1)     # 없어도 에러 없음
a.remove(2)      # 없으면 KeyError 발생
리스트 vs 튜플 vs 집합 비교

리스트 [...] : 순서 있음, 중복 허용, 변경 가능 → 가장 범용적
튜플 (...) : 순서 있음, 중복 허용, 변경 불가 → 안전한 데이터 보관
집합 {...} : 순서 없음, 중복 불허, 변경 가능 → 중복 제거, 집합 연산
Chapter 09

딕셔너리(Dictionary) - 키-값 쌍의 저장소

9.1 딕셔너리란?

딕셔너리는 키(Key)와 값(Value)의 쌍으로 데이터를 저장합니다. 사전에서 단어(키)를 찾으면 뜻(값)이 나오는 것과 같은 원리입니다. 중괄호 {}와 콜론 :으로 만듭니다.

Python
# 딕셔너리 생성
person = {
    "name": "김민수",
    "age": 25,
    "city": "서울",
    "hobbies": ["독서", "코딩", "등산"]
}

# 값 접근
print(person["name"])           # 김민수
print(person.get("age"))       # 25
print(person.get("email", "없음"))  # 없음 (키가 없을 때 기본값)

# 값 추가 / 수정
person["email"] = "minsu@mail.com"   # 추가
person["age"] = 26                     # 수정

# 삭제
del person["city"]
removed = person.pop("email")

# 키/값/쌍 조회
print(person.keys())     # dict_keys(['name', 'age', 'hobbies'])
print(person.values())   # dict_values(['김민수', 26, [...]])
print(person.items())    # dict_items([('name', '김민수'), ...])

# 포함 여부 확인 (키 기준)
print("name" in person)   # True
print("phone" in person)  # False

9.2 딕셔너리 순회

Python
scores = {"국어": 90, "영어": 85, "수학": 92, "과학": 88}

# 키만 순회
for subject in scores:
    print(subject, scores[subject])

# 키-값 쌍 동시 순회 (가장 많이 사용!)
for subject, score in scores.items():
    print(f"{subject}: {score}점")

# 값만 순회
total = 0
for score in scores.values():
    total += score
print(f"총점: {total}, 평균: {total / len(scores)}")
실행 결과
국어: 90점 영어: 85점 수학: 92점 과학: 88점 총점: 355, 평균: 88.75

9.3 중첩 딕셔너리

실무에서는 딕셔너리 안에 딕셔너리, 리스트 등이 중첩된 구조를 매우 자주 만나게 됩니다. JSON 데이터가 대표적입니다.

Python
# 학생 관리 시스템
students = {
    "S001": {
        "name": "김민수",
        "scores": {"국어": 90, "수학": 85}
    },
    "S002": {
        "name": "이영희",
        "scores": {"국어": 95, "수학": 92}
    }
}

# 중첩 접근
print(students["S001"]["name"])              # 김민수
print(students["S002"]["scores"]["수학"])    # 92

# 전체 학생 정보 출력
for sid, info in students.items():
    avg = sum(info["scores"].values()) / len(info["scores"])
    print(f"{sid} {info['name']} - 평균: {avg}")
Tip! 딕셔너리는 파이썬에서 가장 중요한 자료구조 중 하나입니다. API 응답(JSON), 설정 파일, 데이터 변환 등 거의 모든 곳에서 사용됩니다. 키로 접근하면 O(1)의 속도로 값을 가져올 수 있어 리스트보다 검색이 훨씬 빠릅니다.
Chapter 10

조건문 (if / elif / else)

10.1 조건문이란?

조건문은 특정 조건이 참(True)인지 거짓(False)인지에 따라 다른 코드를 실행하는 제어 구조입니다. 프로그래밍에서 "판단"을 담당하며, 거의 모든 프로그램에 핵심적으로 사용됩니다. 파이썬에서는 들여쓰기(Indentation)로 코드 블록을 구분한다는 점이 특히 중요합니다.

10.2 기본 if 문

Python
age = 20

# 기본 if
if age >= 18:
    print("성인입니다.")

# if-else
if age >= 18:
    print("성인입니다.")
else:
    print("미성년자입니다.")

# if-elif-else (다중 조건)
score = 85

if score >= 90:
    grade = "A"
elif score >= 80:
    grade = "B"
elif score >= 70:
    grade = "C"
elif score >= 60:
    grade = "D"
else:
    grade = "F"

print(f"점수: {score}, 등급: {grade}")
# 점수: 85, 등급: B

10.3 중첩 조건문과 복합 조건

Python
# 복합 조건 (and, or, not)
age = 25
has_license = True

if age >= 18 and has_license:
    print("운전할 수 있습니다.")
elif age >= 18 and not has_license:
    print("면허를 먼저 취득하세요.")
else:
    print("아직 운전할 수 없는 나이입니다.")

# in 연산자로 포함 여부 확인
fruit = "사과"
if fruit in ["사과", "배", "포도"]:
    print(f"{fruit}는(은) 과일 목록에 있습니다.")

10.4 삼항 연산자 (조건부 표현식)

간단한 if-else를 한 줄로 작성할 수 있습니다. 값을 조건에 따라 선택할 때 유용합니다.

Python
age = 20

# 기존 if-else
if age >= 18:
    status = "성인"
else:
    status = "미성년"

# 삼항 연산자로 한 줄 처리
status = "성인" if age >= 18 else "미성년"
print(status)  # 성인

# 실전 활용
score = 75
result = "합격" if score >= 60 else "불합격"
print(result)  # 합격
들여쓰기 주의! 파이썬에서 들여쓰기는 문법의 일부입니다. 같은 블록의 코드는 반드시 동일한 깊이로 들여써야 합니다. 공백 4칸이 표준(PEP 8)이며, 탭과 공백을 섞으면 에러가 발생합니다.
Chapter 11

반복문 (for / while)

11.1 for 반복문

for 문은 시퀀스(리스트, 튜플, 문자열, range 등)의 각 요소를 순서대로 하나씩 꺼내어 반복 실행합니다. 파이썬의 for 문은 다른 언어의 "for-each"와 비슷합니다.

Python
# 리스트 순회
fruits = ["사과", "바나나", "포도"]
for fruit in fruits:
    print(f"과일: {fruit}")

# range() 함수로 숫자 반복
for i in range(5):          # 0, 1, 2, 3, 4
    print(i, end=" ")
print()  # 0 1 2 3 4

for i in range(1, 6):       # 1, 2, 3, 4, 5
    print(i, end=" ")
print()  # 1 2 3 4 5

for i in range(0, 10, 2):  # 0, 2, 4, 6, 8 (2씩 증가)
    print(i, end=" ")
print()  # 0 2 4 6 8

# enumerate(): 인덱스와 값을 함께 얻기
for idx, fruit in enumerate(fruits):
    print(f"{idx}번: {fruit}")
# 0번: 사과
# 1번: 바나나
# 2번: 포도

# 문자열 순회
for char in "Python":
    print(char, end="-")
# P-y-t-h-o-n-

11.2 while 반복문

while 문은 조건이 True인 동안 계속 반복합니다. 반복 횟수가 정해지지 않았을 때 사용합니다. 조건이 언젠가는 False가 되도록 해야 무한 루프에 빠지지 않습니다.

Python
# 기본 while
count = 0
while count < 5:
    print(count, end=" ")
    count += 1
# 0 1 2 3 4

# 사용자 입력 반복 (실전 패턴)
while True:
    answer = input("계속하시겠습니까? (y/n): ")
    if answer.lower() == "n":
        print("종료합니다.")
        break
    print("계속 진행...")

11.3 break, continue, else

Python
# break: 반복문 즉시 탈출
for i in range(10):
    if i == 5:
        print("5를 만나서 중단!")
        break
    print(i, end=" ")
# 0 1 2 3 4 5를 만나서 중단!

# continue: 이번 반복만 건너뛰고 다음으로
for i in range(10):
    if i % 2 == 0:   # 짝수이면
        continue       # 건너뛰기
    print(i, end=" ")
# 1 3 5 7 9 (홀수만 출력)

# for-else: break 없이 정상 종료되면 else 실행
numbers = [2, 4, 6, 8]
for num in numbers:
    if num % 2 != 0:
        print(f"홀수 발견: {num}")
        break
else:
    print("모두 짝수입니다!")
# 모두 짝수입니다!

11.4 실전 예제 : 구구단 출력

Python
# 중첩 for문으로 구구단 출력
for dan in range(2, 10):
    print(f"--- {dan}단 ---")
    for i in range(1, 10):
        print(f"{dan} x {i} = {dan * i}")
    print()
Chapter 12

컴프리헨션 (Comprehension)

12.1 리스트 컴프리헨션이란?

컴프리헨션은 파이썬만의 강력하고 우아한 문법입니다. 반복문과 조건문을 한 줄로 압축하여 새로운 리스트(또는 딕셔너리, 집합)를 만들 수 있습니다. 처음에는 낯설 수 있지만, 익숙해지면 코드가 훨씬 간결해집니다.

Python
# 기존 방식: for문으로 제곱 리스트 만들기
squares = []
for i in range(1, 6):
    squares.append(i ** 2)
print(squares)  # [1, 4, 9, 16, 25]

# 리스트 컴프리헨션: 같은 결과를 한 줄로!
squares = [i ** 2 for i in range(1, 6)]
print(squares)  # [1, 4, 9, 16, 25]

# 조건 필터링: 짝수만 골라서 제곱
even_sq = [i ** 2 for i in range(1, 11) if i % 2 == 0]
print(even_sq)  # [4, 16, 36, 64, 100]

# if-else와 함께: 홀짝 분류
labels = ["짝" if i % 2 == 0 else "홀" for i in range(1, 6)]
print(labels)   # ['홀', '짝', '홀', '짝', '홀']

# 문자열에서 모음만 추출
text = "Hello Python World"
vowels = [c for c in text if c.lower() in "aeiou"]
print(vowels)   # ['e', 'o', 'y', 'o', 'o']

12.2 딕셔너리 & 집합 컴프리헨션

Python
# 딕셔너리 컴프리헨션
sq_dict = {x: x**2 for x in range(1, 6)}
print(sq_dict)  # {1: 1, 2: 4, 3: 9, 4: 16, 5: 25}

# 두 리스트를 딕셔너리로 합치기
keys = ["name", "age", "city"]
values = ["김민수", 25, "서울"]
person = {k: v for k, v in zip(keys, values)}
print(person)   # {'name': '김민수', 'age': 25, 'city': '서울'}

# 집합 컴프리헨션
unique_lengths = {len(word) for word in ["hi", "hello", "hey", "ho"]}
print(unique_lengths)  # {2, 5, 3}
컴프리헨션 문법 패턴 정리

[표현식 for 변수 in 반복가능객체] — 기본
[표현식 for 변수 in 반복가능객체 if 조건] — 필터
[A if 조건 else B for 변수 in 반복가능객체] — 변환
{키: 값 for 변수 in 반복가능객체} — 딕셔너리
{표현식 for 변수 in 반복가능객체} — 집합
Chapter 13

함수(Function) 기초

13.1 함수란?

함수는 특정 작업을 수행하는 코드 묶음에 이름을 붙인 것입니다. 같은 코드를 반복 작성하는 대신, 함수로 한 번 정의해 두고 필요할 때마다 호출합니다. 이를 통해 코드의 재사용성, 가독성, 유지보수성이 크게 향상됩니다.

13.2 함수 정의와 호출

Python
# 함수 정의: def 키워드 사용
def greet(name):
    """이름을 받아 인사하는 함수"""
    print(f"안녕하세요, {name}님!")

# 함수 호출
greet("김민수")   # 안녕하세요, 김민수님!
greet("이영희")   # 안녕하세요, 이영희님!

# 반환값이 있는 함수
def add(a, b):
    """두 수를 더한 결과를 반환"""
    return a + b

result = add(3, 5)
print(result)      # 8

# 여러 값 반환 (튜플)
def calc(a, b):
    return a + b, a - b, a * b, a / b

add_r, sub_r, mul_r, div_r = calc(10, 3)
print(f"합:{add_r} 차:{sub_r} 곱:{mul_r} 몫:{div_r:.2f}")
# 합:13 차:7 곱:30 몫:3.33

13.3 매개변수의 종류

Python
# 기본값(Default) 매개변수
def introduce(name, age=20, city="서울"):
    print(f"{name}, {age}세, {city}")

introduce("김민수")              # 김민수, 20세, 서울
introduce("이영희", 25)          # 이영희, 25세, 서울
introduce("박철수", 30, "부산") # 박철수, 30세, 부산

# 키워드 인자: 순서 상관없이 이름으로 전달
introduce(city="대전", name="정수진", age=28)
# 정수진, 28세, 대전

# *args: 가변 위치 인자 (튜플로 받음)
def total(*numbers):
    print(f"인자: {numbers}")
    return sum(numbers)

print(total(1, 2, 3))         # 인자: (1, 2, 3) → 6
print(total(10, 20, 30, 40))  # 인자: (10, 20, 30, 40) → 100

# **kwargs: 가변 키워드 인자 (딕셔너리로 받음)
def print_info(**kwargs):
    for key, value in kwargs.items():
        print(f"{key}: {value}")

print_info(name="김민수", age=25, city="서울")
# name: 김민수
# age: 25
# city: 서울
Tip! 함수의 docstring(삼중 따옴표로 작성한 설명)은 help(함수명)이나 함수명.__doc__으로 확인할 수 있습니다. 좋은 함수에는 항상 docstring이 있습니다.
Chapter 14

함수 심화

14.1 변수 스코프 (Scope)

변수가 어디에서 접근 가능한지를 결정하는 규칙을 스코프라고 합니다. 함수 안에서 만든 변수는 함수 밖에서 사용할 수 없습니다.

Python
x = 10  # 전역 변수 (global)

def my_func():
    y = 20  # 지역 변수 (local) - 함수 안에서만 존재
    print(f"함수 안: x={x}, y={y}")

my_func()           # 함수 안: x=10, y=20
print(f"함수 밖: x={x}")
# print(y)          # NameError! y는 함수 밖에서 접근 불가

# global 키워드로 전역 변수 수정
counter = 0
def increment():
    global counter
    counter += 1

increment()
increment()
print(counter)  # 2

14.2 람다(Lambda) 함수

람다 함수는 이름 없는 한 줄짜리 함수입니다. 간단한 연산을 함수로 전달해야 할 때(정렬 기준, 필터 조건 등) 유용합니다.

Python
# 일반 함수
def square(x):
    return x ** 2

# 같은 기능의 람다 함수
square = lambda x: x ** 2
print(square(5))  # 25

# 실전 활용: 정렬 기준 지정
students = [
    {"name": "김민수", "score": 85},
    {"name": "이영희", "score": 92},
    {"name": "박철수", "score": 78},
]

# 점수 기준 내림차순 정렬
students.sort(key=lambda s: s["score"], reverse=True)
for s in students:
    print(f"{s['name']}: {s['score']}점")
# 이영희: 92점
# 김민수: 85점
# 박철수: 78점

14.3 map, filter, zip

Python
# map(): 모든 요소에 함수 적용
numbers = [1, 2, 3, 4, 5]
squared = list(map(lambda x: x**2, numbers))
print(squared)  # [1, 4, 9, 16, 25]

# filter(): 조건에 맞는 요소만 추출
evens = list(filter(lambda x: x % 2 == 0, numbers))
print(evens)    # [2, 4]

# zip(): 여러 리스트를 병렬로 묶기
names = ["김", "이", "박"]
scores = [90, 85, 78]
for name, score in zip(names, scores):
    print(f"{name}: {score}점")
Chapter 15

클래스와 객체 (OOP 기초)

15.1 객체지향 프로그래밍(OOP)이란?

객체지향 프로그래밍은 프로그램을 객체(Object)들의 상호작용으로 구성하는 방법론입니다. 객체는 데이터(속성)와 기능(메서드)을 하나로 묶은 것이며, 클래스(Class)는 객체를 만들기 위한 설계도입니다. 붕어빵 틀(클래스)과 붕어빵(객체)의 관계로 이해하면 쉽습니다.

15.2 클래스 정의와 인스턴스 생성

Python
class Dog:
    """강아지를 나타내는 클래스"""

    # 생성자: 인스턴스가 만들어질 때 자동 호출
    def __init__(self, name, breed, age):
        self.name = name      # 인스턴스 속성
        self.breed = breed
        self.age = age

    # 메서드 (인스턴스 함수)
    def bark(self):
        print(f"{self.name}: 멍멍!")

    def info(self):
        print(f"이름: {self.name}, 견종: {self.breed}, 나이: {self.age}세")

# 인스턴스(객체) 생성
my_dog = Dog("초코", "골든리트리버", 3)
your_dog = Dog("뭉치", "시바견", 5)

# 메서드 호출
my_dog.bark()   # 초코: 멍멍!
my_dog.info()   # 이름: 초코, 견종: 골든리트리버, 나이: 3세

# 속성 접근
print(my_dog.name)    # 초코
my_dog.age = 4        # 속성 수정

15.3 __str__과 __repr__

Python
class Product:
    def __init__(self, name, price):
        self.name = name
        self.price = price

    def __str__(self):
        # print()로 출력할 때 사용
        return f"{self.name} - {self.price:,}원"

    def __repr__(self):
        # 개발자용 상세 표현
        return f"Product('{self.name}', {self.price})"

item = Product("무선 키보드", 45000)
print(item)       # 무선 키보드 - 45,000원
print(repr(item)) # Product('무선 키보드', 45000)
self란? self는 인스턴스 자기 자신을 가리키는 참조입니다. 메서드를 정의할 때 첫 번째 매개변수로 반드시 넣어야 하며, 호출할 때는 파이썬이 자동으로 전달합니다. my_dog.bark()를 호출하면 Dog.bark(my_dog)와 동일합니다.
Chapter 16

상속과 다형성

16.1 상속(Inheritance)

상속은 기존 클래스(부모 클래스)의 속성과 메서드를 물려받아 새로운 클래스(자식 클래스)를 만드는 것입니다. 코드 재사용을 극대화하고, "is-a" 관계를 표현합니다.

Python
# 부모 클래스
class Animal:
    def __init__(self, name, sound):
        self.name = name
        self.sound = sound

    def speak(self):
        print(f"{self.name}: {self.sound}")

    def info(self):
        print(f"동물 이름: {self.name}")

# 자식 클래스: Animal을 상속
class Dog(Animal):
    def __init__(self, name, breed):
        super().__init__(name, "멍멍")  # 부모 생성자 호출
        self.breed = breed

    def fetch(self):
        print(f"{self.name}가 공을 물어옵니다!")

class Cat(Animal):
    def __init__(self, name, color):
        super().__init__(name, "야옹")
        self.color = color

    def purr(self):
        print(f"{self.name}가 그르릉 소리를 냅니다.")

# 사용
dog = Dog("초코", "골든리트리버")
cat = Cat("나비", "흰색")

dog.speak()    # 초코: 멍멍 (부모 메서드 사용)
dog.fetch()    # 초코가 공을 물어옵니다! (자식 고유 메서드)
cat.speak()    # 나비: 야옹
cat.purr()     # 나비가 그르릉 소리를 냅니다.

16.2 메서드 오버라이딩과 다형성

Python
class Shape:
    def area(self):
        raise NotImplementedError("하위 클래스에서 구현하세요")

class Circle(Shape):
    def __init__(self, radius):
        self.radius = radius

    def area(self):
        return 3.14159 * self.radius ** 2

class Rectangle(Shape):
    def __init__(self, width, height):
        self.width = width
        self.height = height

    def area(self):
        return self.width * self.height

# 다형성: 같은 메서드를 서로 다르게 동작
shapes = [Circle(5), Rectangle(4, 6), Circle(3)]
for shape in shapes:
    print(f"{shape.__class__.__name__} 넓이: {shape.area():.2f}")
# Circle 넓이: 78.54
# Rectangle 넓이: 24.00
# Circle 넓이: 28.27
Chapter 17

모듈과 패키지

17.1 모듈(Module)이란?

모듈은 파이썬 코드가 담긴 .py 파일 하나입니다. 함수, 클래스, 변수를 다른 파일에서 가져다 쓸 수 있게 합니다. 패키지(Package)는 관련 모듈들을 폴더로 묶은 것입니다. 파이썬은 수많은 내장 모듈과 30만 개 이상의 외부 패키지를 제공합니다.

Python
# 모듈 전체 import
import math
print(math.pi)           # 3.141592653589793
print(math.sqrt(16))     # 4.0
print(math.ceil(3.2))    # 4
print(math.floor(3.8))   # 3

# 별칭(alias) 사용
import datetime as dt
now = dt.datetime.now()
print(now.strftime("%Y-%m-%d %H:%M:%S"))

# 특정 요소만 import
from random import randint, choice
print(randint(1, 100))          # 1~100 사이 랜덤 정수
print(choice(["가위", "바위", "보"]))  # 랜덤 선택

# 유용한 내장 모듈들
import os            # 운영체제 상호작용
import json          # JSON 처리
import csv           # CSV 파일 처리
import re            # 정규표현식
import collections   # 고급 자료구조
import itertools     # 반복 도구

17.2 나만의 모듈 만들기

Python — my_utils.py
# my_utils.py (모듈 파일)
def greet(name):
    return f"안녕하세요, {name}님!"

def add_tax(price, rate=0.1):
    return price * (1 + rate)

PI = 3.14159
Python — main.py
# main.py (사용하는 파일)
import my_utils

print(my_utils.greet("김민수"))     # 안녕하세요, 김민수님!
print(my_utils.add_tax(10000))     # 11000.0
print(my_utils.PI)                  # 3.14159
Chapter 18

파일 입출력

18.1 파일 읽고 쓰기 기본

프로그램의 데이터를 영구적으로 저장하거나, 외부 데이터를 불러올 때 파일 입출력이 필요합니다. 파이썬은 open() 함수로 파일을 열고, with 문을 사용하면 자동으로 파일을 닫아줍니다.

Python
# 파일 쓰기 (w: write - 기존 내용 덮어쓰기)
with open("hello.txt", "w", encoding="utf-8") as f:
    f.write("안녕하세요!\n")
    f.write("파이썬 파일 입출력입니다.\n")
    f.write("재미있죠?\n")

# 파일 읽기 (r: read)
with open("hello.txt", "r", encoding="utf-8") as f:
    content = f.read()         # 전체 읽기
    print(content)

# 줄 단위로 읽기
with open("hello.txt", "r", encoding="utf-8") as f:
    for line in f:
        print(line.strip())    # strip()으로 줄바꿈 제거

# 파일 추가 (a: append - 기존 내용 뒤에 추가)
with open("hello.txt", "a", encoding="utf-8") as f:
    f.write("추가된 내용입니다.\n")

18.2 JSON 파일 다루기

JSON은 웹에서 데이터를 주고받을 때 가장 많이 사용되는 형식입니다. 파이썬의 딕셔너리와 구조가 거의 동일하여 상호 변환이 간편합니다.

Python
import json

# 딕셔너리 → JSON 파일 저장
data = {
    "name": "김민수",
    "age": 25,
    "scores": [90, 85, 92],
    "is_student": True
}

with open("data.json", "w", encoding="utf-8") as f:
    json.dump(data, f, ensure_ascii=False, indent=2)

# JSON 파일 → 딕셔너리 읽기
with open("data.json", "r", encoding="utf-8") as f:
    loaded = json.load(f)

print(loaded["name"])     # 김민수
print(loaded["scores"])   # [90, 85, 92]
주의! 파일을 열 때 encoding="utf-8"을 명시하지 않으면, Windows에서 한글이 깨질 수 있습니다. 항상 인코딩을 지정하는 습관을 들이세요.
Chapter 19

예외 처리 (try / except)

19.1 예외란?

예외(Exception)는 프로그램 실행 중 발생하는 에러입니다. 예외가 처리되지 않으면 프로그램이 즉시 중단됩니다. try-except 구문을 사용하면 예외를 잡아서 적절히 처리하고, 프로그램이 계속 실행되도록 할 수 있습니다.

Python
# 기본 try-except
try:
    num = int(input("숫자를 입력하세요: "))
    result = 100 / num
    print(f"결과: {result}")
except ValueError:
    print("숫자를 입력해야 합니다!")
except ZeroDivisionError:
    print("0으로 나눌 수 없습니다!")
except Exception as e:
    print(f"예상치 못한 에러: {e}")
else:
    print("에러 없이 성공!")         # 예외 없을 때만 실행
finally:
    print("항상 실행되는 코드")       # 예외 여부와 무관하게 항상 실행

19.2 주요 예외 종류

예외발생 상황예시
ValueError값의 타입은 맞지만 내용이 잘못됨int("hello")
TypeError연산/함수에 잘못된 타입 사용"2" + 3
ZeroDivisionError0으로 나누기10 / 0
IndexError인덱스 범위 초과lst[100]
KeyError딕셔너리에 없는 키d["없는키"]
FileNotFoundError존재하지 않는 파일 열기open("없는파일.txt")
AttributeError객체에 없는 속성/메서드 접근(1).append(2)
ImportError모듈 import 실패import 없는모듈

19.3 실전 패턴: 안전한 입력 받기

Python
def get_positive_int(prompt):
    """양의 정수를 입력받을 때까지 반복"""
    while True:
        try:
            value = int(input(prompt))
            if value <= 0:
                print("양의 정수를 입력해주세요.")
                continue
            return value
        except ValueError:
            print("올바른 숫자를 입력해주세요.")

age = get_positive_int("나이를 입력하세요: ")
print(f"입력된 나이: {age}")
Chapter 20

주요 내장 함수 모음

20.1 자주 쓰는 내장 함수

파이썬은 별도의 import 없이 바로 사용할 수 있는 내장 함수(built-in functions)를 제공합니다. 이 중 실무에서 가장 많이 쓰이는 함수들을 정리합니다.

Python
numbers = [3, 7, 1, 9, 2, 5]

# 수학 관련
print(len(numbers))      # 6  (길이)
print(sum(numbers))      # 27 (합계)
print(min(numbers))      # 1  (최소)
print(max(numbers))      # 9  (최대)
print(abs(-42))          # 42 (절대값)
print(round(3.7))        # 4  (반올림)
print(round(3.14159, 2)) # 3.14 (소수점 2자리)
print(pow(2, 10))        # 1024 (거듭제곱)

# 정렬/반전
print(sorted(numbers))              # [1, 2, 3, 5, 7, 9]
print(sorted(numbers, reverse=True)) # [9, 7, 5, 3, 2, 1]
print(list(reversed(numbers)))      # [5, 2, 9, 1, 7, 3]

# 타입 확인/변환
print(type(42))           # <class 'int'>
print(isinstance(42, int)) # True

# any / all
print(any([False, False, True]))  # True  (하나라도 True?)
print(all([True, True, True]))    # True  (모두 True?)
print(all([True, False, True]))   # False

# enumerate, zip, range (이미 배움)
# map, filter (이미 배움)
Chapter 21

문자열 포매팅 완전 정복

21.1 f-string (권장!)

Python 3.6부터 도입된 f-string은 가장 직관적이고 빠른 문자열 포매팅 방법입니다. 문자열 앞에 f를 붙이고, 중괄호 {} 안에 변수나 표현식을 넣습니다.

Python
name = "김민수"
age = 25
score = 88.5

# 기본 사용
print(f"이름: {name}, 나이: {age}")

# 표현식 사용
print(f"내년 나이: {age + 1}")
print(f"이름 길이: {len(name)}")

# 서식 지정
print(f"점수: {score:.1f}")           # 소수점 1자리: 88.5
print(f"비율: {score/100:.2%}")       # 퍼센트: 88.50%
print(f"가격: {45000:,}원")            # 천단위 쉼표: 45,000원
print(f"번호: {42:05d}")              # 0 채우기: 00042

# 정렬
print(f"{name:10}|")     # 왼쪽 정렬: '김민수       |'
print(f"{name:>10}|")    # 오른쪽 정렬: '       김민수|'
print(f"{name:^10}|")    # 가운데 정렬: '   김민수    |'

21.2 다른 포매팅 방법 (참고)

Python
# .format() 메서드 (Python 2.7+)
print("이름: {}, 나이: {}".format(name, age))
print("이름: {n}, 나이: {a}".format(n=name, a=age))

# % 연산자 (오래된 방식, 레거시 코드에서 볼 수 있음)
print("이름: %s, 나이: %d" % (name, age))
Tip! 새로 작성하는 코드에서는 f-string을 사용하세요. 가독성과 성능 모두 가장 우수합니다. 다른 방법은 기존 코드를 읽을 때 알아두면 유용합니다.
Chapter 22

정규 표현식 (Regular Expression)

22.1 정규 표현식이란?

정규 표현식(regex)은 문자열에서 특정 패턴을 찾거나 치환하기 위한 미니 언어입니다. 이메일 검증, 전화번호 추출, 로그 파싱 등 텍스트 처리에 강력한 도구입니다. 파이썬에서는 re 모듈을 사용합니다.

Python
import re

text = "연락처: 010-1234-5678, 이메일: test@mail.com"

# 패턴 검색
phone = re.search(r'\d{3}-\d{4}-\d{4}', text)
if phone:
    print(f"전화번호: {phone.group()}")
# 전화번호: 010-1234-5678

# 이메일 추출
email = re.search(r'[\w.+-]+@[\w-]+\.[\w.]+', text)
if email:
    print(f"이메일: {email.group()}")
# 이메일: test@mail.com

# 모든 숫자 찾기
numbers = re.findall(r'\d+', text)
print(numbers)  # ['010', '1234', '5678']

# 패턴 치환
masked = re.sub(r'\d{4}-\d{4}', '****-****', text)
print(masked)
# 연락처: 010-****-****, 이메일: test@mail.com

22.2 주요 정규식 패턴

패턴의미예시 매치
\d숫자 (0-9)3, 42
\w단어 문자 (알파벳, 숫자, _)hello, abc_123
\s공백 문자스페이스, 탭, 줄바꿈
.아무 문자 1개 (줄바꿈 제외)a, 1, @
*0회 이상 반복ab* → a, ab, abb...
+1회 이상 반복ab+ → ab, abb...
{n}정확히 n번 반복\d{3} → 010
[abc]a, b, c 중 하나a 또는 b 또는 c
^문자열 시작^Hello
$문자열 끝world$
Chapter 23

가상환경과 pip

23.1 가상환경이 필요한 이유

프로젝트마다 필요한 라이브러리와 버전이 다릅니다. A 프로젝트에서는 Django 4.0을, B 프로젝트에서는 Django 5.0을 사용한다면? 가상환경(Virtual Environment)을 사용하면 프로젝트별로 독립된 파이썬 환경을 만들 수 있습니다.

Terminal
# 가상환경 생성
python -m venv myenv

# 가상환경 활성화
# Windows:
myenv\Scripts\activate
# macOS / Linux:
source myenv/bin/activate

# 활성화되면 프롬프트에 (myenv)가 표시됩니다
# (myenv) $

# 패키지 설치
pip install requests
pip install pandas numpy matplotlib

# 설치된 패키지 목록
pip list
pip freeze

# requirements.txt로 저장 / 복원
pip freeze > requirements.txt
pip install -r requirements.txt

# 가상환경 비활성화
deactivate
pip 주요 명령어 정리

pip install 패키지명 — 패키지 설치
pip install 패키지명==1.0.0 — 특정 버전 설치
pip uninstall 패키지명 — 패키지 제거
pip list — 설치된 패키지 목록
pip show 패키지명 — 패키지 정보 확인
pip install --upgrade 패키지명 — 패키지 업그레이드
Chapter 24

실전 미니 프로젝트

지금까지 배운 내용을 종합하여, 실제로 동작하는 미니 프로젝트를 만들어 봅니다.

24.1 연락처 관리 프로그램

Python
import json
import os

FILE_NAME = "contacts.json"

def load_contacts():
    """파일에서 연락처 불러오기"""
    if os.path.exists(FILE_NAME):
        with open(FILE_NAME, "r", encoding="utf-8") as f:
            return json.load(f)
    return {}

def save_contacts(contacts):
    """파일에 연락처 저장"""
    with open(FILE_NAME, "w", encoding="utf-8") as f:
        json.dump(contacts, f, ensure_ascii=False, indent=2)

def add_contact(contacts):
    """연락처 추가"""
    name = input("이름: ").strip()
    phone = input("전화번호: ").strip()
    email = input("이메일: ").strip()
    contacts[name] = {"phone": phone, "email": email}
    save_contacts(contacts)
    print(f"✓ '{name}' 추가 완료!")

def search_contact(contacts):
    """연락처 검색"""
    keyword = input("검색어: ").strip()
    found = {k: v for k, v in contacts.items()
             if keyword in k}
    if found:
        for name, info in found.items():
            print(f"  {name} | {info['phone']} | {info['email']}")
    else:
        print("검색 결과가 없습니다.")

def list_contacts(contacts):
    """전체 목록 출력"""
    if not contacts:
        print("연락처가 비어 있습니다.")
        return
    print(f"\n{'이름':<10} {'전화번호':<16} {'이메일'}")
    print("-" * 50)
    for name, info in contacts.items():
        print(f"{name:10} {info['phone']:16} {info['email']}")

def main():
    contacts = load_contacts()
    print("=== 연락처 관리 프로그램 ===")

    while True:
        print("\n[1] 추가  [2] 검색  [3] 목록  [4] 종료")
        choice = input("선택: ").strip()

        if choice == "1":
            add_contact(contacts)
        elif choice == "2":
            search_contact(contacts)
        elif choice == "3":
            list_contacts(contacts)
        elif choice == "4":
            print("프로그램을 종료합니다.")
            break
        else:
            print("올바른 번호를 선택해주세요.")

if __name__ == "__main__":
    main()

24.2 성적 분석 프로그램

Python
class Student:
    def __init__(self, name, scores):
        self.name = name
        self.scores = scores  # dict: {"국어": 90, "수학": 85, ...}

    def average(self):
        return sum(self.scores.values()) / len(self.scores)

    def grade(self):
        avg = self.average()
        if avg >= 90: return "A"
        elif avg >= 80: return "B"
        elif avg >= 70: return "C"
        elif avg >= 60: return "D"
        else: return "F"

    def __str__(self):
        return f"{self.name:6} | 평균: {self.average():6.1f} | 등급: {self.grade()}"

# 학생 데이터
students = [
    Student("김민수", {"국어": 90, "영어": 85, "수학": 92}),
    Student("이영희", {"국어": 78, "영어": 92, "수학": 88}),
    Student("박철수", {"국어": 65, "영어": 70, "수학": 55}),
    Student("정수진", {"국어": 95, "영어": 98, "수학": 97}),
    Student("최동현", {"국어": 82, "영어": 75, "수학": 80}),
]

# 전체 성적표
print("=== 성적 분석 결과 ===")
for s in students:
    print(s)

# 전체 평균
class_avg = sum(s.average() for s in students) / len(students)
print(f"\n전체 평균: {class_avg:.1f}")

# 1등 찾기
top = max(students, key=lambda s: s.average())
print(f"1등: {top.name} ({top.average():.1f}점)")

# 등급별 인원수
from collections import Counter
grade_counts = Counter(s.grade() for s in students)
print(f"등급 분포: {dict(grade_counts)}")
실행 결과
=== 성적 분석 결과 === 김민수 | 평균: 89.0 | 등급: B 이영희 | 평균: 86.0 | 등급: B 박철수 | 평균: 63.3 | 등급: D 정수진 | 평균: 96.7 | 등급: A 최동현 | 평균: 79.0 | 등급: C 전체 평균: 82.8 1등: 정수진 (96.7점) 등급 분포: {'B': 2, 'D': 1, 'A': 1, 'C': 1}

24.3 단어 빈도수 분석기

Python
import re
from collections import Counter

def analyze_text(text):
    """텍스트의 단어 빈도를 분석하는 함수"""
    # 소문자 변환 후 단어 추출
    words = re.findall(r'[가-힣a-zA-Z]+', text.lower())

    # 기본 통계
    print(f"총 단어 수: {len(words)}")
    print(f"고유 단어 수: {len(set(words))}")

    # 빈도수 상위 10개
    counter = Counter(words)
    print("\n--- 빈도수 TOP 10 ---")
    for word, count in counter.most_common(10):
        bar = "█" * count
        print(f"{word:10} {count:3}{bar}")

# 예시 텍스트
sample = """
파이썬은 배우기 쉬운 프로그래밍 언어입니다.
파이썬은 데이터 분석에 많이 사용됩니다.
파이썬으로 웹 개발도 할 수 있고 인공지능 개발도 할 수 있습니다.
프로그래밍을 처음 배우는 사람에게 파이썬을 추천합니다.
"""

analyze_text(sample)
프로젝트 아이디어! 위의 예제를 확장하여 자신만의 프로젝트를 만들어 보세요. 할 일 관리(Todo), 가계부, 단어장, 퀴즈 게임, 날씨 정보 조회(API 활용), 웹 스크래퍼 등 다양한 주제가 가능합니다.
Chapter 25

부록 — Python 치트시트 & 학습 로드맵

25.1 Python 핵심 문법 치트시트

Python Cheat Sheet
# ==============================================
#   Python 치트시트 - 한눈에 보는 핵심 문법
# ==============================================

# ── 1. 변수 & 데이터 타입 ──
x = 10              # int   (정수)
y = 3.14            # float (실수)
s = "hello"         # str   (문자열)
b = True             # bool  (불리언)
n = None             # NoneType (값 없음)
type(x)              # 타입 확인
int() float() str() bool()  # 타입 변환

# ── 2. 문자열 ──
s = "Hello World"
s[0]  s[-1]  s[1:5]  s[::-1]    # 인덱싱 & 슬라이싱
s.upper()  s.lower()  s.strip()   # 변환
s.split()  s.replace("a", "b")    # 분리 & 치환
s.find("sub")  s.count("l")       # 검색
f"name: {name}, age: {age}"      # f-string 포매팅

# ── 3. 리스트 ──
lst = [1, 2, 3]
lst.append(x)  lst.insert(i, x)  lst.extend(other)
lst.pop()  lst.remove(x)  del lst[i]  lst.clear()
lst.sort()  lst.reverse()  lst.copy()
len(lst)  x in lst  lst.index(x)  lst.count(x)

# ── 4. 딕셔너리 ──
d = {"key": "value"}
d["key"]  d.get("key", default)
d.keys()  d.values()  d.items()
d.pop("key")  d.update(other)  "key" in d

# ── 5. 튜플 & 집합 ──
t = (1, 2, 3)            # 불변(immutable)
s = {1, 2, 3}            # 중복 불허, 순서 없음
s1 | s2   s1 & s2   s1 - s2   # 합/교/차집합

# ── 6. 조건문 ──
if 조건A:
    ...
elif 조건B:
    ...
else:
    ...
result = A if 조건 else B     # 삼항 연산자

# ── 7. 반복문 ──
for item in iterable:
    ...
for i in range(start, stop, step):
    ...
for idx, val in enumerate(lst):
    ...
while 조건:
    ...
break   continue              # 흐름 제어

# ── 8. 컴프리헨션 ──
[x**2 for x in range(10)]             # 리스트
[x for x in lst if x > 0]            # 필터
{k: v for k, v in items}             # 딕셔너리
{x for x in lst}                     # 집합

# ── 9. 함수 ──
def func(a, b=10, *args, **kwargs):
    """docstring"""
    return result
lambda x: x ** 2                      # 익명 함수

# ── 10. 클래스 ──
class MyClass(ParentClass):
    def __init__(self, value):
        super().__init__()
        self.value = value
    def method(self):
        return self.value

# ── 11. 예외 처리 ──
try:
    ...
except ErrorType as e:
    ...
else:        # 에러 없을 때
    ...
finally:     # 항상 실행
    ...

# ── 12. 파일 I/O ──
with open("file.txt", "r", encoding="utf-8") as f:
    content = f.read()
# 모드: r(읽기) w(쓰기-덮어씀) a(추가) rb/wb(바이너리)

# ── 13. 유용한 내장 함수 ──
print()  input()  len()  type()  range()
int()  float()  str()  list()  dict()  set()  tuple()
sum()  min()  max()  abs()  round()  sorted()
enumerate()  zip()  map()  filter()
any()  all()  isinstance()  hasattr()

# ── 14. 모듈 import ──
import module
from module import func
import module as alias

25.2 자주 하는 실수 & 해결법

실수증상해결법
들여쓰기 섞어 쓰기IndentationError탭 대신 공백 4칸 통일 (에디터 설정)
= vs == 혼동잘못된 할당 또는 비교=은 할당, ==은 비교
리스트 b = a 복사원본도 함께 변경됨b = a.copy() 또는 b = a[:]
input() 타입 착각TypeError: 문자열 + 숫자int(input(...))으로 변환
가변 기본값 사용함수 호출마다 값이 누적됨def f(lst=None): 패턴 사용
for문에서 리스트 수정요소 건너뛰기, 무한 루프새 리스트 만들기 또는 복사본 순회
파일 닫기 누락데이터 손실, 리소스 누수with open() 사용 (자동 닫힘)
전역 변수 남용디버깅 어려움, 사이드 이펙트함수 매개변수와 반환값 활용
인코딩 미지정한글 깨짐 (Windows)encoding="utf-8" 항상 명시
0부터 시작하는 인덱스IndexError, off-by-one인덱스는 0부터! len-1이 마지막

25.3 PEP 8 주요 스타일 가이드

PEP 8은 파이썬 공식 코딩 스타일 가이드입니다. 협업 시 코드 일관성을 유지하는 데 필수적입니다.

들여쓰기 : 공백 4칸 (탭 사용 금지)
한 줄 최대 길이 : 79자 권장 (최대 120자)
변수/함수명 : snake_case (예: my_variable, calculate_total)
클래스명 : PascalCase (예: MyClass, StudentInfo)
상수 : UPPER_SNAKE_CASE (예: MAX_SIZE, PI)
import 순서 : ① 표준 라이브러리 → ② 서드파티 → ③ 로컬 모듈 (각 그룹 사이 빈 줄)
빈 줄 : 함수/클래스 사이 2줄, 메서드 사이 1줄
연산자 주위 : 공백 1칸 (예: x = 1 + 2, 단 f(a=1)은 공백 없음)

25.4 학습 로드맵

단계기간학습 내용이 튜토리얼
Level 1 입문1~2주변수, 타입, 연산자, 문자열, 조건문, 반복문Ch.1 ~ Ch.11
Level 2 기초2~4주자료구조, 함수, 컴프리헨션, 모듈Ch.7 ~ Ch.17
Level 3 중급1~2개월OOP, 파일I/O, 예외처리, 정규식, 가상환경Ch.15 ~ Ch.23
Level 4 전문2~3개월데코레이터, 제너레이터, 비동기, 웹/데이터/AI 프레임워크추가 학습
Level 5 실무지속실전 프로젝트, 코드 리뷰, 오픈소스 기여, 성능 최적화지속적 성장

25.5 마치며

축하합니다! 전 25장의 Python 기초 완전정복 튜토리얼을 모두 마치셨습니다.

파이썬은 단순히 프로그래밍 언어를 넘어, 문제 해결의 도구입니다. 복잡한 데이터를 분석하고, 반복적인 업무를 자동화하고, 아이디어를 빠르게 프로토타입으로 만들 수 있습니다. 개발자뿐만 아니라 마케터, 기획자, 연구자 등 다양한 직군에서 파이썬 역량이 경쟁력이 되고 있습니다.

이 튜토리얼의 모든 예제를 직접 타이핑하고, 변형해 보고, 나만의 프로젝트에 적용해 보세요.

파이썬 학습의 핵심 3원칙

1. 직접 타이핑하세요 — 복사-붙여넣기 대신 직접 입력하면 손이 기억합니다. 오타를 수정하는 과정에서 문법이 체득됩니다.

2. 에러를 두려워하지 마세요 — 에러 메시지는 적이 아니라 선생님입니다. 메시지를 차근히 읽으면 어디가 잘못됐는지 알려줍니다. 모든 숙련된 개발자는 수만 번의 에러를 경험했습니다.

3. 나만의 프로젝트를 만드세요 — 관심 있는 주제(가계부, 게임, 웹 크롤러, 챗봇 등)로 직접 프로젝트를 만들어 보세요. 실제 문제를 풀면서 배우는 것이 가장 빠르고 즐겁습니다.

코드의 세계에 오신 것을 환영합니다. 이 튜토리얼이 여러분의 파이썬 여정에 든든한 첫걸음이 되기를 바랍니다!