← 파이썬 강의 목록으로
🌱
기초 (Basic)
dict · key/value · get/items · set · 합/교/차 · 메서드 · split/join · f-string 심화 · 이스케이프 · def · return · 기본값 · 키워드 인수 · 스코프 · 1~9주차 통합 · 프로젝트 설계 · 디버깅

7~10주차 — 딕셔너리와 집합 · 문자열 다루기 · 함수 기초 · 기초 종합 실습

키로 값을 빠르게 찾는 딕셔너리, 자주 쓰는 메서드(get, items, in), 중복 없는 집합과 합/교/차/대칭차 연산, 그리고 자료구조 선택 기준을 익힙니다. 문자열 인덱싱/슬라이싱, 자주 쓰는 메서드(split/join/strip/replace), f-string 심화(정렬·자릿수·진법), 이스케이프 문자(\n \t)를 익힙니다. def 로 함수를 정의하고 호출, 매개변수와 인수의 차이, 기본값/키워드 인수, return으로 값 반환, 그리고 지역/전역 변수의 스코프를 익힙니다. 지금까지 배운 입력·조건·반복·자료구조·함수를 자연스럽게 조합해 작은 프로그램을 완성합니다. To-Do List, 단어장 퀴즈, 가계부, 숫자 야구 중 하나를 골라 만들어보세요.

dictsetkey-valueinstringsplitjoinf-string함수defreturnscope종합실습프로젝트디버깅캡스톤
소요 시간
⏱ 2시간 + 2시간 + 2시간 + 3시간 이상 (분할)
난이도
📊 완전 초보
선수 조건
🎯 6주차
결과물
딕셔너리로 데이터 모델링 + 집합 연산으로 중복 제거 / 회문/이메일 검증/텍스트 통계 같은 문자열 처리 프로그램 / 재사용 가능한 함수로 깔끔하게 분리된 작은 프로그램 / 직접 동작하는 콘솔 프로그램 1개 + README + 시연 자료

이 강의에서 배우는 것

  • 1딕셔너리 생성·키 접근·수정
  • 2자주 쓰는 메서드 (get, items, keys)
  • 3집합(set) 연산 (합집합/교집합/차집합)
  • 4자료구조 선택 기준
  • 5문자열 인덱싱·슬라이싱
  • 6자주 쓰는 메서드 (split, join, strip, replace 등)
  • 7f-string 심화 (정렬·자릿수)
  • 8이스케이프 문자 (\n, \t)
  • 9def 로 함수를 정의하고 호출한다
  • 10매개변수와 인수의 차이를 안다
  • 11기본값 매개변수, 키워드 인수를 사용한다
  • 12return 으로 값을 반환한다
  • 13변수의 스코프(지역/전역)를 이해한다
  • 14지금까지 배운 모든 내용을 합쳐 작은 프로그램을 완성한다
  • 15입력·조건·반복·자료구조·함수를 자연스럽게 조합한다
  • 16디버깅과 코드 정리 경험을 쌓는다

7주차 — 딕셔너리와 집합

키로 값을 빠르게 찾는 딕셔너리, 자주 쓰는 메서드(get, items, in), 중복 없는 집합과 합/교/차/대칭차 연산, 그리고 자료구조 선택 기준을 익힙니다.

1. 딕셔너리란

키(key) → 값(value) 의 매핑. 순서 X (3.7+ 부터는 입력 순서 유지). 중괄호 {...}.

python
student = {"name": "홍길동", "age": 20, "major": "CS"}

print(student["name"])      # 홍길동
student["age"] = 21         # 수정
student["email"] = "..."    # 추가
del student["major"]        # 삭제

키는 보통 문자열 또는 숫자, 값은 어떤 타입이든 가능.

2. 자주 쓰는 메서드

python
d = {"a": 1, "b": 2, "c": 3}

print(d.keys())     # dict_keys(['a', 'b', 'c'])
print(d.values())   # dict_values([1, 2, 3])
print(d.items())    # dict_items([('a', 1), ...])

# get: 안전하게 조회 (키 없어도 에러 X)
print(d.get("z"))            # None
print(d.get("z", "기본값"))  # 기본값

# in: 키 존재 확인
print("a" in d)     # True

3. 딕셔너리 순회

python
for key in d:                    # 키만
    print(key)

for key, value in d.items():     # 키-값 동시
    print(f"{key} = {value}")

4. 집합 (set)

중복 없는 원소의 모음. 순서 X. 중괄호 {...} (단, 빈 set은 set()).

python
fruits = {"사과", "바나나", "포도"}
fruits.add("딸기")
fruits.discard("바나나")    # 없으면 무시
print(len(fruits))

# 중복 자동 제거
nums = [1, 2, 2, 3, 3, 3]
unique = set(nums)         # {1, 2, 3}

5. 집합 연산

python
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}

6. 자료구조 선택 기준

상황선택
순서 중요, 인덱스로 접근리스트
변경 불필요, 빠르게튜플
키로 값 조회딕셔너리
중복 제거, 멤버십 검사집합

7. 자주 하는 실수

1) 존재하지 않는 키 접근

python
d = {"a": 1}
print(d["z"])    # KeyError

→ d.get("z") 사용 또는 if "z" in d:

2) 빈 set을 {}로 만들기

python
s = {}    # 빈 딕셔너리!
s = set() # 빈 set

3) set에 리스트 넣기

python
{[1, 2]}    # TypeError: unhashable type: 'list'
{(1, 2)}    # 튜플은 OK

4) 딕셔너리 순회 중 수정

python
for k in d:
    del d[k]   # RuntimeError

→ 키 목록을 미리 복사: for k in list(d):

8. FAQ

Q1. 딕셔너리의 키 중복 시?

마지막 값으로 덮어씀. 키는 유일해야 함.

Q2. 딕셔너리는 정렬되나요?

Python 3.7+ 부터 입력 순서 유지. 정렬은 sorted(d.items()).

Q3. 집합과 딕셔너리 둘 다 {} 인데 어떻게 구분?

: 가 있으면 딕셔너리, 없으면 집합. {1, 2} = set, {1: "a"} = dict.

8주차 — 문자열 다루기

문자열 인덱싱/슬라이싱, 자주 쓰는 메서드(split/join/strip/replace), f-string 심화(정렬·자릿수·진법), 이스케이프 문자(\n \t)를 익힙니다.

1. 문자열 기초

문자열은 변경 불가능(immutable). 인덱싱과 슬라이싱은 리스트와 동일.

python
s = "Python"
print(s[0])         # P
print(s[-1])        # n
print(s[1:4])       # yth
print(len(s))       # 6

# s[0] = "X"  # TypeError — 변경 불가

2. 자주 쓰는 메서드

메서드동작예시
lower() / upper()소/대문자"Hi".upper() → "HI"
strip()양쪽 공백 제거" hi ".strip() → "hi"
lstrip() / rstrip()좌/우 공백 제거
split(sep)분리 → 리스트"a,b,c".split(",") → ["a","b","c"]
join(seq)리스트 → 문자열",".join(["a","b"]) → "a,b"
replace(old, new)치환"foo".replace("o", "*") → "f**"
find(x) / index(x)위치 찾기"hello".find("l") → 2
count(x)개수"hello".count("l") → 2
startswith / endswith시작/끝 검사"abc".endswith("c") → True
isdigit / isalpha숫자/문자 검사

3. f-string 심화

python
name = "Alice"
score = 92.345

print(f"{name:<10}|")       # 좌측 정렬 폭 10
print(f"{name:>10}|")       # 우측 정렬
print(f"{name:^10}|")       # 가운데
print(f"{name:*^10}|")      # 채움 문자 * 가운데

print(f"{score:.2f}")        # 92.35  (소수점 둘째)
print(f"{1234567:,}")        # 1,234,567  (천 단위 콤마)
print(f"{0.85:.0%}")         # 85%
print(f"{255:b} {255:x}")    # 2진수, 16진수

4. 이스케이프 문자

표기의미
\n줄바꿈
\t탭
\\백슬래시
\"큰따옴표
\'작은따옴표
python
print("줄1\n줄2")        # 두 줄
print("이름\t나이")      # 탭으로 구분
print("경로: C:\\dev")    # C:\dev

# raw string: 이스케이프 무시
print(r"C:\dev\new")      # C:\dev\new

5. 문자열 ↔ 리스트 변환

python
csv = "사과,바나나,포도"
fruits = csv.split(",")             # ['사과', '바나나', '포도']

joined = " | ".join(fruits)         # "사과 | 바나나 | 포도"

6. 자주 하는 실수

1) 문자열 원본을 수정하려 함

python
s = "hello"
s.replace("l", "L")    # s는 그대로!
s = s.replace("l", "L")  # 결과를 다시 할당

2) split() 인자 누락

"a b c".split() 은 공백 분리. "a,b".split() 은 분리 안 됨.

3) find vs index

find 는 없으면 -1, index 는 ValueError.

4) 따옴표 안에 같은 따옴표

python
s = "say "hi""    # SyntaxError
s = 'say "hi"'    # OK
s = "say \"hi\""  # OK

5) f-string 중괄호 출력

python
print(f"{name}")     # 변수
print(f"{{name}}")   # 그냥 {name} 출력

7. FAQ

Q1. 문자열 길이는 한글도 1글자로?

len() 은 코드 포인트 단위라 보통 1글자. 이모지·결합문자는 예외 있음.

Q2. 대소문자 무시 비교는?

s1.lower() == s2.lower() 또는 s1.casefold() == s2.casefold() (더 정확).

Q3. 문자열 안에 변수 값을 넣는 방법이 여럿?

옛 방식: %, .format(). 현재 권장: f-string (가장 빠르고 가독성 좋음).

9주차 — 함수 기초

def 로 함수를 정의하고 호출, 매개변수와 인수의 차이, 기본값/키워드 인수, return으로 값 반환, 그리고 지역/전역 변수의 스코프를 익힙니다.

1. 함수란

같은 동작을 여러 번 쓰지 않고 이름 붙여 재사용. 코드를 짧고 명확하게 만든다.

python
def greet(name):
    print(f"안녕, {name}!")

greet("홍길동")
greet("김영희")

2. 매개변수와 인수

  • 매개변수(parameter): 함수 정의의 변수 (name)
  • 인수(argument): 함수 호출 시 전달하는 값 ("홍길동")
python
def add(a, b):       # a, b: 매개변수
    return a + b

result = add(3, 5)   # 3, 5: 인수

3. return

함수가 값을 돌려줍니다. return 만나면 즉시 종료.

python
def square(x):
    return x * x

n = square(5)   # 25

return 없으면 자동으로 None 반환.

4. 기본값 매개변수

호출 시 인수 생략하면 기본값 사용.

python
def greet(name, greeting="안녕"):
    return f"{greeting}, {name}님!"

print(greet("길동"))                # 안녕, 길동님!
print(greet("Alice", "Hello"))     # Hello, Alice님!

5. 키워드 인수

순서 대신 이름으로 전달.

python
def make_user(name, age, city):
    return {"name": name, "age": age, "city": city}

# 위치 인수
u1 = make_user("홍길동", 20, "서울")

# 키워드 인수 (순서 무관, 가독성 좋음)
u2 = make_user(city="부산", name="김영희", age=25)

6. 여러 값 반환 (튜플)

python
def min_max(nums):
    return min(nums), max(nums)

lo, hi = min_max([3, 1, 4, 1, 5])
print(lo, hi)   # 1 5

7. 변수 스코프

함수 안에서 만든 변수는 지역 변수 — 밖에서 안 보임.

python
def f():
    x = 10        # 지역
    print(x)

f()
# print(x)        # NameError

함수 안에서 전역 변수를 수정하려면 global 키워드:

python
total = 0
def add(n):
    global total
    total += n

(가능하면 global 은 피하고, 함수가 값을 받아서 반환하는 형태 권장.)

8. 자주 하는 실수

1) 함수 호출에 () 빠뜨림

python
def hi():
    print("hi")
hi    # 함수 객체. 실행 안 됨
hi()  # 실행

2) return 없는데 결과 사용

python
def show(x):
    print(x)
y = show(5)   # y = None

3) 기본값에 가변 객체

python
def add_to(item, lst=[]):    # ⚠️ 함정!
    lst.append(item)
    return lst
add_to(1)   # [1]
add_to(2)   # [1, 2] — 같은 리스트 공유

→ 기본값은 None 으로 두고 함수 안에서 새로 생성:

python
def add_to(item, lst=None):
    if lst is None:
        lst = []
    ...

4) 이름 충돌

python
def list():        # 내장 list 가려짐
    ...

→ print, list, sum 같은 내장 이름은 변수·함수명으로 쓰지 말 것.

9. FAQ

Q1. 함수는 몇 줄이 적절한가요?

권장 5~30줄. 너무 길면 더 작은 함수로 분리.

Q2. print 와 return 의 차이?

print 는 화면에 출력, return 은 값을 반환. 함수가 값 자체가 필요할 때는 return.

Q3. 함수 안에서 함수를 호출할 수 있나요?

네. 자신을 호출(재귀)도 가능 (중급에서 다룸).

10주차 — 기초 종합 실습

지금까지 배운 입력·조건·반복·자료구조·함수를 자연스럽게 조합해 작은 프로그램을 완성합니다. To-Do List, 단어장 퀴즈, 가계부, 숫자 야구 중 하나를 골라 만들어보세요.

1. 프로젝트 설계 절차

  1. 요구사항 정리 — 무엇을 만드는지, 어떤 입출력인지 종이에 적기
  2. 데이터 구조 결정 — 리스트? 딕셔너리? 둘 다?
  3. 함수 분리 — 작은 단위로 (입력 받기, 처리, 출력 등)
  4. 흐름 작성 — main 루프, 종료 조건
  5. 점진적으로 만들기 — 한 번에 다 짜지 말고 한 기능씩 동작 확인

2. 디버깅 기초

print 디버깅

가장 단순하고 강력한 방법.

python
def calc(x, y):
    print(f"DEBUG: x={x}, y={y}")
    result = x / y
    print(f"DEBUG: result={result}")
    return result

에러 메시지 읽기

가장 아래의 한 줄이 핵심.

text
Traceback (most recent call last):
  File "main.py", line 10, in <module>
    print(scores[5])
IndexError: list index out of range

→ "10번째 줄에서 리스트 인덱스 범위 초과"

3. 골격 예제 — 미니 To-Do List

examples/todo_skeleton.py 참고. 함수로 분리하고, 메인 루프에서 조립.

4. 자주 하는 실수

  1. 한꺼번에 모든 기능 구현 시도 — 작게 잘라서 단계별로
  2. 함수 분리 없이 한 덩어리 코드 — 읽기 어렵고 디버깅 힘듦
  3. 에러를 try: ... except: pass 로 숨김 — 어디서 뭐가 잘못됐는지 모름
  4. 변수명을 a, b, temp 로 — 의미 있는 이름 (scores, user_input)

5. FAQ

Q1. 어디서부터 시작해야 할지 모르겠어요.

"프로그램이 시작되면 무엇이 화면에 나오는가" → "사용자가 무엇을 입력하는가" → 그 흐름을 그대로 코드로.

Q2. 막히면 어떻게 해요?

한 줄씩 print로 출력해서 데이터를 확인. 그래도 안 되면 검색 (StackOverflow). 그래도 안 되면 질문.

6. 다음 단계

기초 과정을 마쳤습니다! 🎉

  • 중급 과정 — 함수 심화, OOP, 파일 I/O
  • 실습 도전 — Lv1 기초응용, Lv2 자료구조 콘솔 프로젝트

💻 예제 (examples)

실제로 실행해 결과를 확인할 수 있는 예제 코드입니다.

01_dict_basic.py— 딕셔너리 생성/수정/삭제
CODE
student = {"name": "홍길동", "age": 20, "major": "CS"}
print(student["name"])

student["age"] = 21
student["email"] = "h@example.com"
del student["major"]
print(student)
▶ 실행 결과
홍길동
{'name': '홍길동', 'age': 21, 'email': 'h@example.com'}
02_dict_methods.py— get, items, in
CODE
d = {"a": 1, "b": 2, "c": 3}

print(d.keys())
print(d.values())
print(d.items())

print(d.get("z"))             # None
print(d.get("z", "기본값"))   # 기본값
print("a" in d)               # True

for k, v in d.items():
    print(f"{k} = {v}")
▶ 실행 결과
dict_keys(['a', 'b', 'c'])
dict_values([1, 2, 3])
dict_items([('a', 1), ('b', 2), ('c', 3)])
None
기본값
True
a = 1
b = 2
c = 3
03_set.py— 집합 생성과 4가지 연산
CODE
a = {1, 2, 3, 4}
b = {3, 4, 5, 6}

print(a | b)    # 합집합
print(a & b)    # 교집합
print(a - b)    # 차집합
print(a ^ b)    # 대칭차

# 리스트 중복 제거
nums = [1, 2, 2, 3, 3, 3]
print(list(set(nums)))
▶ 실행 결과
{1, 2, 3, 4, 5, 6}
{3, 4}
{1, 2}
{1, 2, 5, 6}
[1, 2, 3]
04_word_count.py— 단어 빈도 카운트 (딕셔너리 활용)
CODE
text = "apple banana apple cherry banana apple"
words = text.split()

count = {}
for w in words:
    count[w] = count.get(w, 0) + 1

print(count)
▶ 실행 결과
{'apple': 3, 'banana': 2, 'cherry': 1}
01_methods.py— 자주 쓰는 메서드 모음
CODE
s = "  Hello, World!  "

print(s.strip())              # "Hello, World!"
print(s.upper())              # "  HELLO, WORLD!  "
print(s.lower())              # "  hello, world!  "
print(s.replace("World", "Python"))  # "  Hello, Python!  "
print("hello".startswith("he"))      # True
print("hello".endswith("lo"))        # True
print("123".isdigit())               # True
print("abc".isalpha())               # True
▶ 실행 결과
Hello, World!
  HELLO, WORLD!
  hello, world!
  Hello, Python!
True
True
True
True
02_split_join.py— split / join 패턴
CODE
# split
csv = "사과,바나나,포도"
fruits = csv.split(",")
print(fruits)

words = "Hello World Python".split()  # 공백 분리
print(words)

# join
joined = " | ".join(fruits)
print(joined)

print("-".join(["010", "1234", "5678"]))
▶ 실행 결과
['사과', '바나나', '포도']
['Hello', 'World', 'Python']
사과 | 바나나 | 포도
010-1234-5678
03_fstring_format.py— f-string 정렬·자릿수·진법
CODE
name = "Alice"
score = 92.345

print(f"{name:<10}|")
print(f"{name:>10}|")
print(f"{name:^10}|")
print(f"{name:*^10}|")

print(f"{score:.2f}")
print(f"{1234567:,}")
print(f"{0.85:.0%}")
print(f"{255:b} {255:x}")
▶ 실행 결과
Alice     |
     Alice|
  Alice   |
**Alice***|
92.35
1,234,567
85%
11111111 ff
04_escape.py— 이스케이프 + raw string
CODE
print("줄1\n줄2")
print("이름\t나이")
print("경로: C:\\dev\\app")

# raw string
print(r"C:\dev\new")

# 따옴표 안의 따옴표
print("she said \"hi\"")
print('she said "hi"')
▶ 실행 결과
줄1
줄2
이름	나이
경로: C:\dev\app
C:\dev\new
she said "hi"
she said "hi"
01_basic_function.py— 정의와 호출
CODE
def greet(name):
    print(f"안녕, {name}!")

def add(a, b):
    return a + b

greet("홍길동")
greet("김영희")
print(add(3, 5))
▶ 실행 결과
안녕, 홍길동!
안녕, 김영희!
8
02_default_args.py— 기본값 + 키워드 인수
CODE
def greet(name, greeting="안녕"):
    return f"{greeting}, {name}님!"

print(greet("길동"))
print(greet("Alice", "Hello"))
print(greet(name="민수", greeting="반가워"))
▶ 실행 결과
안녕, 길동님!
Hello, Alice님!
반가워, 민수님!
03_return.py— return / 여러 값 반환
CODE
def square(x):
    return x * x

def min_max(nums):
    return min(nums), max(nums)

print(square(5))

lo, hi = min_max([3, 1, 4, 1, 5])
print(lo, hi)
▶ 실행 결과
25
1 5
04_scope.py— 지역 변수 / global
CODE
total = 0

def add(n):
    global total
    total += n

add(10)
add(20)
print(total)   # 30

def local_demo():
    x = 100
    print(x)

local_demo()
# print(x)  # NameError
▶ 실행 결과
30
100
todo_skeleton.py— To-Do List 골격 — 함수 분리 + main 루프
CODE
def show_menu():
    print("\n[명령] add / list / done <번호> / del <번호> / quit")

def add_todo(todos, text):
    todos.append({"text": text, "done": False})

def show_list(todos):
    if not todos:
        print("(비어 있음)")
        return
    for i, t in enumerate(todos, start=1):
        mark = "x" if t["done"] else " "
        print(f"{i}. [{mark}] {t['text']}")

def main():
    todos = []
    while True:
        show_menu()
        cmd = input("> ").strip()
        if cmd == "quit":
            break
        elif cmd == "list":
            show_list(todos)
        elif cmd.startswith("add "):
            add_todo(todos, cmd[4:])
            print("추가됨")
        # done, del 도 비슷한 패턴

if __name__ == "__main__":
    main()
▶ 실행 결과
[명령] add / list / done <번호> / del <번호> / quit
> add 우유 사기
추가됨
> list
1. [ ] 우유 사기
> quit
debug_demo.py— print 디버깅 + try-except 맛보기
CODE
def divide(a, b):
    print(f"DEBUG: a={a}, b={b}")
    try:
        result = a / b
    except ZeroDivisionError as e:
        print(f"에러: {e}")
        return None
    print(f"DEBUG: result={result}")
    return result

print(divide(10, 2))
print(divide(10, 0))
▶ 실행 결과
DEBUG: a=10, b=2
DEBUG: result=5.0
5.0
DEBUG: a=10, b=0
에러: division by zero
None

📝 과제 (exercises)

직접 풀어보고, 막힐 때 정답을 펼쳐 비교해보세요.

과제 1

연락처 프로그램

목표: 이름으로 전화번호를 저장/조회/삭제하는 CLI.

요구사항
  • 데이터: {"이름": "전화번호"} 딕셔너리
  • 명령: add, find, del, list, quit
  • find 시 없는 이름은 "찾을 수 없습니다"
입출력 예시
명령: add
이름: 홍길동
전화: 010-1234-5678
추가됨

명령: find
이름: 홍길동
홍길동: 010-1234-5678

명령: list
1. 홍길동: 010-1234-5678
▶정답 코드 펼치기 / 접기
SOLUTION
contacts = {}

while True:
    cmd = input("명령(add/find/del/list/quit): ")
    if cmd == "quit":
        break
    elif cmd == "add":
        name = input("이름: ")
        phone = input("전화: ")
        contacts[name] = phone
        print("추가됨")
    elif cmd == "find":
        name = input("이름: ")
        if name in contacts:
            print(f"{name}: {contacts[name]}")
        else:
            print("찾을 수 없습니다")
    elif cmd == "del":
        name = input("이름: ")
        if name in contacts:
            del contacts[name]
            print("삭제됨")
        else:
            print("찾을 수 없습니다")
    elif cmd == "list":
        for i, (name, phone) in enumerate(contacts.items(), start=1):
            print(f"{i}. {name}: {phone}")
▶ 실행 결과
명령(add/find/del/list/quit): add
이름: 홍길동
전화: 010-1234-5678
추가됨
명령(add/find/del/list/quit): list
1. 홍길동: 010-1234-5678
명령(add/find/del/list/quit): quit
과제 2

단어 빈도 Top 3

목표: 긴 문장에서 가장 많이 등장한 단어 3개를 출력한다.

요구사항
  • 입력은 코드 안에 변수로 (긴 문장)
  • 단어는 공백으로 분리
  • 빈도 내림차순으로 정렬, 상위 3개
💡 힌트

sorted(d.items(), key=lambda x: x[1], reverse=True) 로 값 기준 정렬

입출력 예시
1. apple: 5번
2. banana: 3번
3. cherry: 2번
▶정답 코드 펼치기 / 접기
SOLUTION
text = "apple banana apple cherry banana apple cherry apple banana apple"

words = text.split()
count = {}
for w in words:
    count[w] = count.get(w, 0) + 1

top3 = sorted(count.items(), key=lambda x: x[1], reverse=True)[:3]
for i, (word, n) in enumerate(top3, start=1):
    print(f"{i}. {word}: {n}번")
▶ 실행 결과
1. apple: 5번
2. banana: 3번
3. cherry: 2번
과제 3

중복 제거 (순서 유지)

목표: 리스트에서 중복을 제거하되 원래 입력 순서를 유지한다.

요구사항
  • 입력: ["a", "b", "a", "c", "b", "d"]
  • 출력: ["a", "b", "c", "d"]
  • set() 만으로는 순서가 깨질 수 있음 → 딕셔너리 활용
💡 힌트

dict.fromkeys(리스트) 활용

▶정답 코드 펼치기 / 접기
SOLUTION
items = ["a", "b", "a", "c", "b", "d"]

# 방법 1: dict.fromkeys (가장 간결, 순서 유지)
result = list(dict.fromkeys(items))
print(result)

# 방법 2: 직접 순회
seen = set()
result2 = []
for x in items:
    if x not in seen:
        seen.add(x)
        result2.append(x)
print(result2)
▶ 실행 결과
['a', 'b', 'c', 'd']
['a', 'b', 'c', 'd']
과제 4

회문(palindrome) 판별

목표: 입력 문자열이 앞뒤가 같은지 확인한다.

요구사항
  • 공백, 대소문자 무시
  • 회문이면 "회문입니다", 아니면 "회문이 아닙니다"
입출력 예시
문자열: 기러기
회문입니다

문자열: A man a plan a canal Panama
회문입니다
▶정답 코드 펼치기 / 접기
SOLUTION
s = input("문자열: ")
clean = s.replace(" ", "").lower()

if clean == clean[::-1]:
    print("회문입니다")
else:
    print("회문이 아닙니다")
▶ 실행 결과
문자열: A man a plan a canal Panama
회문입니다
과제 5

이메일 형식 검증

목표: 이메일 주소가 형식에 맞는지 간단히 확인한다.

요구사항
  • @ 가 정확히 1개
  • . 이 @ 뒤에 1개 이상
  • 공백 없음
입출력 예시
이메일: hong@example.com
유효한 이메일

이메일: foo@@bar.com
잘못된 형식
▶정답 코드 펼치기 / 접기
SOLUTION
email = input("이메일: ")

if " " in email:
    print("잘못된 형식 (공백)")
elif email.count("@") != 1:
    print("잘못된 형식 (@ 개수)")
else:
    local, domain = email.split("@")
    if "." not in domain or not local:
        print("잘못된 형식")
    else:
        print("유효한 이메일")
▶ 실행 결과
이메일: hong@example.com
유효한 이메일
과제 6

텍스트 통계

목표: 문장을 입력받아 글자 수, 단어 수, 평균 단어 길이를 출력한다.

요구사항
  • 글자 수는 공백 제외
  • 단어 수는 공백으로 분리한 결과
  • 평균 단어 길이는 소수점 둘째 자리
입출력 예시
문장: Hello Python world

글자 수(공백 제외): 16
단어 수: 3
평균 단어 길이: 5.33
▶정답 코드 펼치기 / 접기
SOLUTION
text = input("문장: ")

chars = len(text.replace(" ", ""))
words = text.split()
word_count = len(words)
avg = sum(len(w) for w in words) / word_count

print(f"글자 수(공백 제외): {chars}")
print(f"단어 수: {word_count}")
print(f"평균 단어 길이: {avg:.2f}")
▶ 실행 결과
문장: Hello Python world
글자 수(공백 제외): 16
단어 수: 3
평균 단어 길이: 5.33
과제 7

계산기 함수 모음

목표: 사칙연산 함수를 만들고 메뉴형 계산기로 사용한다.

요구사항
  • 함수 4개: add, sub, mul, div
  • div 는 0으로 나누면 None 반환 (또는 메시지)
  • main 흐름: 메뉴 → 두 수 입력 → 결과 출력 → 종료
입출력 예시
[메뉴] 1.+ 2.- 3.* 4./ 5.종료
선택: 1
첫 번째 수: 10
두 번째 수: 5
결과: 15
▶정답 코드 펼치기 / 접기
SOLUTION
def add(a, b): return a + b
def sub(a, b): return a - b
def mul(a, b): return a * b
def div(a, b):
    if b == 0:
        return None
    return a / b

while True:
    print("\n[메뉴] 1.+ 2.- 3.* 4./ 5.종료")
    choice = input("선택: ")
    if choice == "5":
        break
    a = float(input("첫 번째 수: "))
    b = float(input("두 번째 수: "))
    if choice == "1":
        print("결과:", add(a, b))
    elif choice == "2":
        print("결과:", sub(a, b))
    elif choice == "3":
        print("결과:", mul(a, b))
    elif choice == "4":
        result = div(a, b)
        print("결과:", "0으로 나눌 수 없습니다" if result is None else result)
▶ 실행 결과
[메뉴] 1.+ 2.- 3.* 4./ 5.종료
선택: 1
첫 번째 수: 10
두 번째 수: 5
결과: 15.0
과제 8

입력 검증 함수

목표: is_valid_age(value) 함수를 만든다.

요구사항
  • 0~120 사이의 정수면 True, 아니면 False
  • 문자열이 들어와도 처리 ("abc" → False)
입출력 예시
True
True
True
False
False
False
▶정답 코드 펼치기 / 접기
SOLUTION
def is_valid_age(value):
    try:
        n = int(value)
    except (ValueError, TypeError):
        return False
    return 0 <= n <= 120

print(is_valid_age(20))
print(is_valid_age(0))
print(is_valid_age(120))
print(is_valid_age(-1))
print(is_valid_age(150))
print(is_valid_age("abc"))
▶ 실행 결과
True
True
True
False
False
False
과제 9

소수 판별 함수

목표: is_prime(n) 함수를 작성하고, 1~50 중 소수만 출력한다.

요구사항
  • 1과 0 이하: 소수 아님
  • 2: 소수
  • 짝수(2 제외): 소수 아님
  • 그 외: 3부터 √n 까지 홀수로 나누어 보기
입출력 예시
1~50 사이의 소수:
2 3 5 7 11 13 17 19 23 29 31 37 41 43 47
▶정답 코드 펼치기 / 접기
SOLUTION
def is_prime(n):
    if n <= 1:
        return False
    if n == 2:
        return True
    if n % 2 == 0:
        return False
    i = 3
    while i * i <= n:
        if n % i == 0:
            return False
        i += 2
    return True

primes = [str(n) for n in range(1, 51) if is_prime(n)]
print("1~50 사이의 소수:")
print(" ".join(primes))
▶ 실행 결과
1~50 사이의 소수:
2 3 5 7 11 13 17 19 23 29 31 37 41 43 47
과제 10

콘솔 To-Do List

목표: 할 일 추가/조회/완료/삭제 명령이 모두 동작하는 콘솔 프로그램.

요구사항
  • 데이터 구조: 리스트 + 딕셔너리 조합
  • 명령: add, list, done <번호>, del <번호>, quit
  • 잘못된 명령 / 존재하지 않는 번호 처리
입출력 예시
> add 우유 사기
추가됨
> list
1. [ ] 우유 사기
2. [x] 책 읽기
> done 1
1번 완료
> del 2
2번 삭제
채점
  • · 5개 명령 모두 동작 — 60%
  • · 잘못된 입력 처리 — 20%
  • · 코드 정리(함수 분리) — 20%
▶정답 코드 펼치기 / 접기
SOLUTION
def add_todo(todos, text):
    todos.append({"text": text, "done": False})

def list_todos(todos):
    if not todos:
        print("(비어 있음)")
        return
    for i, t in enumerate(todos, start=1):
        mark = "x" if t["done"] else " "
        print(f"{i}. [{mark}] {t['text']}")

def done_todo(todos, idx):
    if 1 <= idx <= len(todos):
        todos[idx-1]["done"] = True
        print(f"{idx}번 완료")
    else:
        print("번호 오류")

def del_todo(todos, idx):
    if 1 <= idx <= len(todos):
        del todos[idx-1]
        print(f"{idx}번 삭제")
    else:
        print("번호 오류")

def main():
    todos = []
    while True:
        cmd = input("> ").strip()
        if cmd == "quit":
            break
        elif cmd == "list":
            list_todos(todos)
        elif cmd.startswith("add "):
            add_todo(todos, cmd[4:])
            print("추가됨")
        elif cmd.startswith("done "):
            try:
                done_todo(todos, int(cmd[5:]))
            except ValueError:
                print("숫자를 입력하세요")
        elif cmd.startswith("del "):
            try:
                del_todo(todos, int(cmd[4:]))
            except ValueError:
                print("숫자를 입력하세요")
        else:
            print("알 수 없는 명령")

main()
▶ 실행 결과
> add 우유 사기
추가됨
> list
1. [ ] 우유 사기
> done 1
1번 완료
> quit
과제 11

단어장 퀴즈

목표: 영-한 단어장으로 랜덤 퀴즈를 출제한다.

요구사항
  • 단어장은 코드 안에 딕셔너리로 (10개 이상)
  • 10문제 출제 (중복 가능)
  • 정답/오답 즉시 알림
  • 마지막에 점수 출력
입출력 예시
[1/10] apple의 뜻은? 사과
정답!
[2/10] book의 뜻은? 가방
오답. 정답: 책
...
총점: 7 / 10
▶정답 코드 펼치기 / 접기
SOLUTION
import random

vocab = {
    "apple": "사과", "book": "책", "cat": "고양이", "dog": "강아지",
    "egg": "달걀", "fish": "물고기", "garden": "정원", "house": "집",
    "ice": "얼음", "jacket": "재킷",
}

words = list(vocab.keys())
score = 0

for i in range(1, 11):
    word = random.choice(words)
    answer = input(f"[{i}/10] {word}의 뜻은? ").strip()
    if answer == vocab[word]:
        print("정답!")
        score += 1
    else:
        print(f"오답. 정답: {vocab[word]}")

print(f"\n총점: {score} / 10")
▶ 실행 결과
[1/10] apple의 뜻은? 사과
정답!
[2/10] book의 뜻은? 가방
오답. 정답: 책
...
총점: 7 / 10
과제 12

간이 가계부

목표: 수입/지출을 기록하고 잔액과 카테고리별 합계를 보여준다.

요구사항
  • 데이터: [{type, amount, category, memo}, ...]
  • 명령: add, list, summary, quit
  • summary: 수입 합계, 지출 합계, 잔액, 카테고리별 지출
입출력 예시
> add
수입/지출: 지출
금액: 5000
카테고리: 식비
메모: 점심
추가됨

> summary
수입: 100,000원
지출: 35,000원
잔액: 65,000원

[지출 카테고리별]
식비: 20,000원
교통: 10,000원
기타: 5,000원
▶정답 코드 펼치기 / 접기
SOLUTION
entries = []

def add_entry():
    t = input("수입/지출: ")
    amount = int(input("금액: "))
    category = input("카테고리: ")
    memo = input("메모: ")
    entries.append({"type": t, "amount": amount, "category": category, "memo": memo})
    print("추가됨")

def show_summary():
    income = sum(e["amount"] for e in entries if e["type"] == "수입")
    expense = sum(e["amount"] for e in entries if e["type"] == "지출")
    print(f"수입: {income:,}원")
    print(f"지출: {expense:,}원")
    print(f"잔액: {income - expense:,}원")

    cat = {}
    for e in entries:
        if e["type"] == "지출":
            cat[e["category"]] = cat.get(e["category"], 0) + e["amount"]
    print("\n[지출 카테고리별]")
    for c, v in sorted(cat.items(), key=lambda x: -x[1]):
        print(f"{c}: {v:,}원")

while True:
    cmd = input("> ").strip()
    if cmd == "quit":
        break
    elif cmd == "add":
        add_entry()
    elif cmd == "summary":
        show_summary()
    elif cmd == "list":
        for i, e in enumerate(entries, start=1):
            print(f"{i}. {e['type']} {e['amount']:,}원 ({e['category']}) {e['memo']}")
▶ 실행 결과
> add
수입/지출: 수입
금액: 100000
카테고리: 월급
메모: 11월 월급
추가됨
> summary
수입: 100,000원
지출: 0원
잔액: 100,000원
> quit
예제 코드 / 강의 자료

전체 강의 자료와 예제 코드는 GitHub에서 자유롭게 받아볼 수 있습니다.

GitHub에서 보기 ↗

댓글 0

아직 댓글이 없습니다. 첫 댓글을 남겨 주세요.

댓글은 회원만 쓸 수 있습니다.

광고·욕설·비방·개인정보·불법 내용이 담긴 댓글은 숨기거나 지웁니다. 댓글은 닉네임과 함께 공개됩니다. 개인정보처리방침