파이썬 기초 문법
파이썬 기초 문법¶
참고: 이 레슨은 선수 지식 복습용입니다. 고급 레슨을 시작하기 전에 기초가 부족하다면 이 내용을 먼저 학습하세요.
학습 목표¶
- 파이썬 기본 자료형과 연산자 이해
- 제어문 (조건문, 반복문) 활용
- 함수 정의와 호출 방법 습득
- 자료구조 (리스트, 딕셔너리, 튜플, 세트) 활용
1. 변수와 자료형¶
1.1 기본 자료형¶
# 정수 (int)
age = 25
count = -10
big_number = 1_000_000 # 가독성을 위한 언더스코어
# 실수 (float)
pi = 3.14159
temperature = -40.5
scientific = 2.5e-3 # 0.0025
# 문자열 (str)
name = "Alice"
message = '안녕하세요'
multiline = """여러 줄
문자열입니다"""
# 불리언 (bool)
is_active = True
is_empty = False
# None (값 없음)
result = None
# 타입 확인
print(type(age)) # <class 'int'>
print(type(pi)) # <class 'float'>
print(type(name)) # <class 'str'>
print(type(is_active)) # <class 'bool'>
1.2 타입 변환¶
# 문자열 → 정수/실수
num_str = "123"
num_int = int(num_str) # 123
num_float = float(num_str) # 123.0
# 숫자 → 문자열
age = 25
age_str = str(age) # "25"
# 불리언 변환
bool(0) # False
bool(1) # True
bool("") # False (빈 문자열)
bool("hello") # True
bool([]) # False (빈 리스트)
bool([1, 2]) # True
# 형변환 오류 처리
try:
invalid = int("hello")
except ValueError as e:
print(f"변환 오류: {e}")
1.3 연산자¶
# 산술 연산자
a, b = 10, 3
print(a + b) # 13 (덧셈)
print(a - b) # 7 (뺄셈)
print(a * b) # 30 (곱셈)
print(a / b) # 3.333... (나눗셈, 항상 float)
print(a // b) # 3 (정수 나눗셈)
print(a % b) # 1 (나머지)
print(a ** b) # 1000 (거듭제곱)
# 비교 연산자
print(5 == 5) # True
print(5 != 3) # True
print(5 > 3) # True
print(5 >= 5) # True
print(3 < 5) # True
print(3 <= 3) # True
# 논리 연산자
print(True and False) # False
print(True or False) # True
print(not True) # False
# 멤버십 연산자
fruits = ["apple", "banana"]
print("apple" in fruits) # True
print("orange" not in fruits) # True
# 동일성 연산자 (객체 비교)
a = [1, 2, 3]
b = [1, 2, 3]
c = a
print(a == b) # True (값 비교)
print(a is b) # False (객체 비교)
print(a is c) # True (같은 객체)
2. 문자열 처리¶
2.1 문자열 기본¶
# 문자열 생성
s1 = "Hello"
s2 = 'World'
s3 = """Multi
line"""
# 문자열 연결
greeting = s1 + " " + s2 # "Hello World"
# 문자열 반복
dashes = "-" * 10 # "----------"
# 인덱싱 (0부터 시작)
text = "Python"
print(text[0]) # 'P'
print(text[-1]) # 'n' (마지막)
# 슬라이싱
print(text[0:3]) # 'Pyt' (0~2)
print(text[2:]) # 'thon' (2부터 끝)
print(text[:3]) # 'Pyt' (처음~2)
print(text[::2]) # 'Pto' (2칸씩)
print(text[::-1]) # 'nohtyP' (역순)
2.2 문자열 메서드¶
text = " Hello, World! "
# 공백 제거
print(text.strip()) # "Hello, World!"
print(text.lstrip()) # "Hello, World! "
print(text.rstrip()) # " Hello, World!"
# 대소문자 변환
s = "Hello World"
print(s.upper()) # "HELLO WORLD"
print(s.lower()) # "hello world"
print(s.capitalize()) # "Hello world"
print(s.title()) # "Hello World"
# 검색
print(s.find("World")) # 6 (인덱스)
print(s.find("Python")) # -1 (없음)
print(s.count("o")) # 2
print(s.startswith("He")) # True
print(s.endswith("!")) # False
# 분리와 결합
csv = "a,b,c,d"
parts = csv.split(",") # ['a', 'b', 'c', 'd']
joined = "-".join(parts) # 'a-b-c-d'
# 치환
text = "I like Python"
new_text = text.replace("Python", "Java") # "I like Java"
2.3 포맷팅¶
name = "Alice"
age = 25
score = 95.5
# f-string (권장, Python 3.6+)
print(f"Name: {name}, Age: {age}")
print(f"Score: {score:.2f}") # 소수점 2자리
print(f"Binary: {age:08b}") # 8자리 이진수, 0패딩
# format() 메서드
print("Name: {}, Age: {}".format(name, age))
print("Name: {n}, Age: {a}".format(n=name, a=age))
# % 연산자 (구 방식)
print("Name: %s, Age: %d" % (name, age))
# 정렬
text = "Python"
print(f"{text:>10}") # " Python" (오른쪽 정렬)
print(f"{text:<10}") # "Python " (왼쪽 정렬)
print(f"{text:^10}") # " Python " (가운데 정렬)
print(f"{text:*^10}") # "**Python**" (패딩 문자)
3. 제어문¶
3.1 조건문 (if)¶
# 기본 if-elif-else
score = 85
if score >= 90:
grade = "A"
elif score >= 80:
grade = "B"
elif score >= 70:
grade = "C"
else:
grade = "F"
print(f"Grade: {grade}") # Grade: B
# 삼항 연산자
status = "Pass" if score >= 60 else "Fail"
# 조건식 체이닝
age = 25
if 18 <= age < 65:
print("Working age")
# 진리값 판단
items = [1, 2, 3]
if items: # 비어있지 않으면 True
print("List has items")
# 논리 연산 조합
x, y = 5, 10
if x > 0 and y > 0:
print("Both positive")
if x < 0 or y < 0:
print("At least one negative")
3.2 반복문 (for)¶
# 리스트 반복
fruits = ["apple", "banana", "cherry"]
for fruit in fruits:
print(fruit)
# range 사용
for i in range(5): # 0, 1, 2, 3, 4
print(i)
for i in range(2, 8): # 2, 3, 4, 5, 6, 7
print(i)
for i in range(0, 10, 2): # 0, 2, 4, 6, 8
print(i)
# enumerate (인덱스와 값)
for idx, fruit in enumerate(fruits):
print(f"{idx}: {fruit}")
# zip (여러 시퀀스 병렬 순회)
names = ["Alice", "Bob", "Charlie"]
ages = [25, 30, 35]
for name, age in zip(names, ages):
print(f"{name} is {age}")
# 딕셔너리 반복
person = {"name": "Alice", "age": 25}
for key in person:
print(f"{key}: {person[key]}")
for key, value in person.items():
print(f"{key}: {value}")
# 리스트 컴프리헨션
squares = [x**2 for x in range(10)]
evens = [x for x in range(20) if x % 2 == 0]
3.3 반복문 (while)¶
# 기본 while
count = 0
while count < 5:
print(count)
count += 1
# break와 continue
for i in range(10):
if i == 3:
continue # 3 건너뛰기
if i == 7:
break # 7에서 종료
print(i) # 0, 1, 2, 4, 5, 6
# while-else (break 없이 끝났을 때)
n = 7
i = 2
while i < n:
if n % i == 0:
print(f"{n} is not prime")
break
i += 1
else:
print(f"{n} is prime")
# 무한 루프
while True:
user_input = input("Enter 'quit' to exit: ")
if user_input == "quit":
break
4. 함수¶
4.1 함수 정의¶
# 기본 함수
def greet(name):
"""인사말을 반환합니다."""
return f"Hello, {name}!"
message = greet("Alice")
print(message) # Hello, Alice!
# 여러 값 반환
def divide(a, b):
quotient = a // b
remainder = a % b
return quotient, remainder
q, r = divide(10, 3)
print(f"몫: {q}, 나머지: {r}") # 몫: 3, 나머지: 1
# 기본값 매개변수
def power(base, exp=2):
return base ** exp
print(power(3)) # 9
print(power(3, 3)) # 27
# 키워드 인자
def create_user(name, age, city="Seoul"):
return {"name": name, "age": age, "city": city}
user = create_user(name="Bob", age=30, city="Busan")
4.2 가변 인자¶
# *args (위치 인자)
def sum_all(*args):
"""임의 개수의 숫자 합계"""
return sum(args)
print(sum_all(1, 2, 3)) # 6
print(sum_all(1, 2, 3, 4, 5)) # 15
# **kwargs (키워드 인자)
def print_info(**kwargs):
"""임의 개수의 키-값 출력"""
for key, value in kwargs.items():
print(f"{key}: {value}")
print_info(name="Alice", age=25, city="Seoul")
# 혼합 사용
def mixed_func(required, *args, **kwargs):
print(f"필수: {required}")
print(f"추가 위치: {args}")
print(f"추가 키워드: {kwargs}")
mixed_func("hello", 1, 2, 3, x=10, y=20)
4.3 람다 함수¶
# 기본 람다
square = lambda x: x ** 2
print(square(5)) # 25
# 여러 매개변수
add = lambda a, b: a + b
print(add(3, 4)) # 7
# 정렬에서 활용
students = [
{"name": "Alice", "score": 85},
{"name": "Bob", "score": 92},
{"name": "Charlie", "score": 78}
]
# 점수 기준 정렬
sorted_students = sorted(students, key=lambda x: x["score"], reverse=True)
for s in sorted_students:
print(f"{s['name']}: {s['score']}")
# map, filter와 함께
numbers = [1, 2, 3, 4, 5]
squared = list(map(lambda x: x**2, numbers))
evens = list(filter(lambda x: x % 2 == 0, numbers))
5. 자료구조¶
5.1 리스트 (List)¶
# 리스트 생성
fruits = ["apple", "banana", "cherry"]
numbers = [1, 2, 3, 4, 5]
mixed = [1, "hello", 3.14, True]
empty = []
# 요소 접근
print(fruits[0]) # "apple"
print(fruits[-1]) # "cherry"
# 슬라이싱
print(numbers[1:4]) # [2, 3, 4]
print(numbers[::2]) # [1, 3, 5]
# 요소 수정
fruits[0] = "apricot"
# 요소 추가
fruits.append("date") # 끝에 추가
fruits.insert(1, "blueberry") # 위치 지정 추가
fruits.extend(["elderberry"]) # 여러 개 추가
# 요소 제거
fruits.remove("banana") # 값으로 제거
del fruits[0] # 인덱스로 제거
popped = fruits.pop() # 마지막 제거 및 반환
fruits.clear() # 전체 제거
# 리스트 연산
a = [1, 2, 3]
b = [4, 5, 6]
c = a + b # [1, 2, 3, 4, 5, 6]
d = a * 2 # [1, 2, 3, 1, 2, 3]
# 유용한 메서드
nums = [3, 1, 4, 1, 5, 9, 2]
print(len(nums)) # 7
print(nums.count(1)) # 2
print(nums.index(4)) # 2
nums.sort() # 정렬 (제자리)
nums.reverse() # 역순 (제자리)
5.2 튜플 (Tuple)¶
# 튜플 생성 (불변)
point = (3, 4)
rgb = (255, 128, 0)
single = (42,) # 요소 1개 (쉼표 필수)
# 언패킹
x, y = point
print(f"x={x}, y={y}")
# 함수에서 여러 값 반환
def get_stats(numbers):
return min(numbers), max(numbers), sum(numbers)
minimum, maximum, total = get_stats([1, 2, 3, 4, 5])
# 튜플은 수정 불가
# point[0] = 5 # TypeError!
# 하지만 가변 객체 포함 시 내부는 변경 가능
data = ([1, 2], [3, 4])
data[0].append(3) # 가능! ([1, 2, 3], [3, 4])
# 튜플 ↔ 리스트 변환
t = tuple([1, 2, 3])
l = list((1, 2, 3))
5.3 딕셔너리 (Dictionary)¶
# 딕셔너리 생성
person = {
"name": "Alice",
"age": 25,
"city": "Seoul"
}
# 요소 접근
print(person["name"]) # "Alice"
print(person.get("job")) # None (없을 때)
print(person.get("job", "N/A")) # "N/A" (기본값)
# 요소 추가/수정
person["job"] = "Engineer" # 추가
person["age"] = 26 # 수정
# 요소 삭제
del person["city"]
job = person.pop("job")
person.clear()
# 메서드
person = {"name": "Alice", "age": 25}
print(person.keys()) # dict_keys(['name', 'age'])
print(person.values()) # dict_values(['Alice', 25])
print(person.items()) # dict_items([('name', 'Alice'), ('age', 25)])
# 딕셔너리 컴프리헨션
squares = {x: x**2 for x in range(5)}
# {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}
# 병합 (Python 3.9+)
a = {"x": 1, "y": 2}
b = {"y": 3, "z": 4}
c = a | b # {"x": 1, "y": 3, "z": 4}
# 중첩 딕셔너리
users = {
"user1": {"name": "Alice", "age": 25},
"user2": {"name": "Bob", "age": 30}
}
print(users["user1"]["name"]) # "Alice"
5.4 세트 (Set)¶
# 세트 생성 (중복 없음, 순서 없음)
fruits = {"apple", "banana", "cherry"}
numbers = {1, 2, 3, 3, 2, 1} # {1, 2, 3}
empty = set() # 빈 세트 ({}는 딕셔너리!)
# 요소 추가/제거
fruits.add("date")
fruits.remove("apple") # 없으면 KeyError
fruits.discard("grape") # 없어도 에러 없음
# 집합 연산
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}
print(a ^ b) # 대칭 차집합: {1, 2, 5, 6}
# 부분집합 확인
c = {1, 2}
print(c.issubset(a)) # True
print(a.issuperset(c)) # True
# 리스트 중복 제거
numbers = [1, 2, 2, 3, 3, 3]
unique = list(set(numbers)) # [1, 2, 3]
6. 예외 처리¶
6.1 기본 예외 처리¶
# try-except
try:
result = 10 / 0
except ZeroDivisionError:
print("0으로 나눌 수 없습니다")
# 여러 예외 처리
try:
value = int(input("숫자 입력: "))
result = 10 / value
except ValueError:
print("숫자가 아닙니다")
except ZeroDivisionError:
print("0으로 나눌 수 없습니다")
# 예외 정보 접근
try:
x = int("hello")
except ValueError as e:
print(f"에러 발생: {e}")
# else와 finally
try:
file = open("data.txt", "r")
except FileNotFoundError:
print("파일 없음")
else:
# 예외 없을 때 실행
content = file.read()
file.close()
finally:
# 항상 실행
print("작업 완료")
6.2 예외 발생¶
# 예외 발생시키기
def validate_age(age):
if age < 0:
raise ValueError("나이는 음수일 수 없습니다")
if age > 150:
raise ValueError("나이가 너무 큽니다")
return age
try:
validate_age(-5)
except ValueError as e:
print(f"검증 실패: {e}")
# 커스텀 예외
class InsufficientFundsError(Exception):
"""잔액 부족 예외"""
def __init__(self, balance, amount):
self.balance = balance
self.amount = amount
super().__init__(f"잔액 {balance}원, 출금 요청 {amount}원")
def withdraw(balance, amount):
if amount > balance:
raise InsufficientFundsError(balance, amount)
return balance - amount
try:
withdraw(1000, 2000)
except InsufficientFundsError as e:
print(f"출금 실패: {e}")
7. 파일 입출력¶
7.1 파일 읽기/쓰기¶
# 파일 쓰기
with open("output.txt", "w", encoding="utf-8") as f:
f.write("Hello, World!\n")
f.write("안녕하세요\n")
# 파일 읽기
with open("output.txt", "r", encoding="utf-8") as f:
content = f.read() # 전체 읽기
print(content)
# 줄 단위 읽기
with open("output.txt", "r", encoding="utf-8") as f:
for line in f:
print(line.strip())
# 파일 추가
with open("output.txt", "a", encoding="utf-8") as f:
f.write("추가된 내용\n")
# 파일 모드
# "r" 읽기 (기본)
# "w" 쓰기 (덮어쓰기)
# "a" 추가
# "x" 생성 (이미 있으면 에러)
# "b" 바이너리 모드 (예: "rb", "wb")
7.2 JSON 처리¶
import json
# Python 객체 → JSON
data = {
"name": "Alice",
"age": 25,
"hobbies": ["reading", "coding"]
}
# JSON 문자열로 변환
json_str = json.dumps(data, ensure_ascii=False, indent=2)
print(json_str)
# JSON 파일로 저장
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"])
정리¶
핵심 문법 요약¶
| 개념 | 설명 | 예시 |
|---|---|---|
| 변수 | 값을 저장하는 이름 | x = 10 |
| 자료형 | int, float, str, bool, None | type(x) |
| 리스트 | 순서 있는 가변 시퀀스 | [1, 2, 3] |
| 튜플 | 순서 있는 불변 시퀀스 | (1, 2, 3) |
| 딕셔너리 | 키-값 쌍 | {"a": 1} |
| 세트 | 중복 없는 집합 | {1, 2, 3} |
| if/elif/else | 조건 분기 | if x > 0: |
| for | 시퀀스 순회 | for i in range(10): |
| while | 조건 반복 | while x < 10: |
| 함수 | 재사용 가능한 코드 블록 | def func(): |
| 예외 처리 | 오류 대응 | try/except |
다음 단계¶
이 기초를 마쳤다면 다음 레슨으로: - 16_OOP_Basics.md: 객체지향 프로그래밍 기초 - 01_Type_Hints.md: 타입 힌팅 (고급 레슨 시작)