학습 자료

먼저 보는 문법 한 장 — 이 시리즈에 나오는 것만


Article

이 시리즈는 파이썬을 처음부터 가르치지 않는다. 문서를 자르고 검색하는 데 실제로 쓰는 것만 쓴다.

여기 모아둔 것이 그 전부다. 클래스도, 데코레이터도, async 도 나오지 않는다. 한 번 훑고 시작하면 되고, 막히면 이 페이지로 돌아오면 된다.

여섯 가지면 된다
  1. 문자열 자르기문서를 조각으로
  2. f-string값을 문장에 넣기
  3. 리스트 · 딕셔너리조각과 검색 결과를 담기
  4. 함수같은 일을 한 곳에
  5. 반복가장 많이 쓴다

준비 — 파이썬 켜기

터미널에 python 을 친다. Windows 에서 안 먹으면 py 다.

터미널
  • >>>

>>> 가 보이면 한 줄씩 받아먹을 준비가 된 것이다. 여기서는 값만 쳐도 결과가 나온다. print 를 안 써도 된다.

나갈 때는 exit() 을 치거나 Ctrl + Z 후 엔터. macOS · Linux 는 Ctrl + D 다.


1. 문자열 — 글자를 한 줄로 세운 것

# = 는 "같다"가 아니라 "왼쪽 이름에 오른쪽 값을 넣는다"는 뜻이다
s = "백엔드 개발자는 서버를 다룬다"

len(s)          # len = length(길이). 글자 수를 센다. 공백도 한 글자다
터미널
  • 16

번호로 글자 하나를 꺼낸다. 0부터 센다.

s[0]        # 0번째 = 첫 글자
s[-1]       # 음수는 뒤에서부터. -1 이 마지막
터미널
  • '백'
  • '다'

콜론(:)을 넣으면 구간이 나온다. 이게 「자르기」다.

s[0:3]      # 0번부터 3번 「앞」까지 — 끝 번호는 포함되지 않는다
s[:3]       # 시작을 비우면 처음부터. 위와 같다
s[8:]       # 끝을 비우면 끝까지
s[8:9999]   # 길이를 넘겨도 에러가 아니다. 있는 만큼만 준다
터미널
  • '백엔드'
  • '백엔드'
  • ' 서버를 다룬다'
  • ' 서버를 다룬다'

2. f-string — 문장 안에 값 넣기

따옴표 앞에 f 를 붙이면 중괄호 안이 값으로 바뀐다.

name = "백엔드"
count = 3

print(f"{name} 개발자 {count}명")
터미널
  • 백엔드 개발자 3명

중괄호 안에서는 계산도 되고 함수도 부를 수 있다.

print(f"{count + 1}")           # 계산
print(f"{len(name)}")           # 함수 호출
print(f"{3.14159:.2f}")         # 콜론 뒤는 "어떻게 보여줄지"
print(f"[{count:3d}]")          # 정수를 3칸에 오른쪽 맞춤
print(f"[{name:6s}]")           # 문자열을 6칸에 왼쪽 맞춤
터미널
  • 4
  • 3
  • 3.14
  • [ 3]
  • [백엔드 ]
자주 쓰는 표시 방식
쓰는 법
{x}값 그대로3
{x:.2f}소수점 둘째 자리까지3.14
{x:3d}정수를 3칸에 오른쪽 맞춤 3
{x:6s}문자열을 6칸에 왼쪽 맞춤백엔드
{x[:30]}안에서 슬라이싱앞 30글자

3. 리스트 — 값을 순서대로 담는 상자

대괄호로 만든다. 문자열처럼 번호로 꺼내고, 콜론으로 자른다.

jobs = ["백엔드", "프론트엔드", "데이터"]

len(jobs)       # 문자열에서는 글자 수, 리스트에서는 항목 수
jobs[0]         # 0번이 첫 항목인 것도 문자열과 같다
jobs[-1]        # 뒤에서 첫 항목
jobs[:2]        # 앞의 두 개
터미널
  • 3
  • '백엔드'
  • '데이터'
  • ['백엔드', '프론트엔드']

끝에 하나 붙일 때는 .append() 를 쓴다.

jobs.append("기획")     # 점(.)은 "이 리스트에게 시키는 일"이라는 표시다
jobs
터미널
  • ['백엔드', '프론트엔드', '데이터', '기획']

4. 딕셔너리 — 이름표를 붙여 담는 상자

중괄호로 만들고 이름과 값을 짝지어 담는다. 리스트가 번호로 꺼낸다면 이쪽은 이름으로 꺼낸다.

job = {"name": "백엔드", "years": 3}

job["name"]             # 대괄호에 번호 대신 이름을 넣는다
터미널
  • '백엔드'
job["tool"] = "파이썬"    # 없는 이름에 넣으면 새로 생긴다
job
터미널
  • {'name': '백엔드', 'years': 3, 'tool': '파이썬'}
언제 무엇을 쓰나

리스트

["백엔드", "프론트엔드"]

  • 같은 종류가 여러 개일 때
  • 순서가 있다
  • 조각 목록 · 검색 결과 목록

딕셔너리

{"name": ..., "score": ...}

  • 한 덩어리에 여러 정보가 붙을 때
  • 이름으로 꺼낸다
  • 조각 하나 + 점수 + 출처

5. 함수 — 같은 일을 이름 붙여 한 곳에

# def       "지금부터 함수를 만든다"
# greet     내가 붙인 이름. 앞으로 이 이름으로 부른다
# (name, title="개발자")
#           밖에서 받을 값. title 은 안 주면 "개발자"를 쓴다(기본값)
# 끝의 콜론  "아래 들여쓴 줄이 이 함수의 몸통"이라는 표시
def greet(name, title="개발자"):
    return f"{name} {title}"        # return 은 결과를 함수 밖으로 내보낸다
greet("김철수")                 # title 을 안 줬으니 기본값
greet("김철수", "기획자")        # 줬으니 그걸 쓴다
터미널
  • '김철수 개발자'
  • '김철수 기획자'
def no_return(x):
    x + 1               # 계산만 하고 안 내보낸다

len(no_return(1))
터미널
  • TypeError: object of type 'NoneType' has no len()

기본값이 있는 인자는 반드시 뒤에 온다. def f(a, b=1) 은 되고 def f(a=1, b) 는 에러다. 하나만 주고 불렀을 때 어느 자리인지 알 수 없기 때문이다.


6. 반복 — 가장 많이 쓴다

여기가 제일 중요하다. 앞으로 쓰는 코드의 절반이 반복이다.

① for — 하나씩 꺼내 처리한다

# for A in B:  "B 에서 하나씩 꺼내 A 에 넣고, 아래 줄을 반복하라"
for j in jobs:
    print(j)        # 앞의 공백 4칸이 "이 줄은 for 안쪽"이라는 표시다. 문법이다
터미널
  • 백엔드
  • 프론트엔드
  • 데이터
  • 기획

② enumerate — 번호도 같이 받는다

for i, j in enumerate(jobs):        # 번호와 값을 짝지어 주므로 받는 이름도 두 개
    print(i, j)
터미널
  • 0 백엔드
  • 1 프론트엔드
  • 2 데이터
  • 3 기획

번호가 0부터라 사람이 세는 것과 어긋난다. start=1 하나면 해결된다.

for i, j in enumerate(jobs, start=1):
    print(i, j)
터미널
  • 1 백엔드
  • 2 프론트엔드
  • 3 데이터
  • 4 기획

③ range — 숫자를 차례로 만든다

목록이 없고 숫자만 필요할 때 쓴다. 문서를 일정한 간격으로 자를 때가 그렇다.

list(range(3))              # 0부터 3 「앞」까지
list(range(0, 10, 3))       # 0부터 10 앞까지 3씩 건너뛰며
터미널
  • [0, 1, 2]
  • [0, 3, 6, 9]

끝 번호가 포함되지 않는 것이 슬라이싱과 같은 규칙이다. 그래서 둘을 같이 쓰면 딱 맞아떨어진다.

range 와 슬라이싱이 맞물린다

for start in range(0, len(text), 30):

start = 0
text[0:30]
0~29번
start = 30
text[30:60]
30~59번 — 겹치지 않는다
start = 60
text[60:90]
60~89번

④ 딕셔너리 반복 — .items() 를 잊지 않는다

for k in job:               # 그냥 돌면 이름만 나온다
    print(k)
터미널
  • name
  • years
  • tool
for k, v in job.items():    # .items() 를 붙여야 이름과 값을 짝으로 준다
    print(k, "=", v)
터미널
  • name = 백엔드
  • years = 3
  • tool = 파이썬

⑤ 모아 담기 — 반복의 진짜 쓸모

반복은 화면에 찍으려고 도는 게 아니라 결과를 모으려고 돈다.

result = []                 # 빈 리스트를 먼저 만들고
for j in jobs:
    result.append(len(j))   # 하나씩 쌓는다

result
터미널
  • [3, 5, 3, 2]

⑥ 컴프리헨션 — 위의 세 줄을 한 줄로

리스트를 만들려고 도는 반복문은 파이썬에서 한 줄로 쓴다.

같은 일, 두 가지 표기

반복문으로

세 줄

  • result = []
  • for j in jobs:
  • result.append(len(j))

컴프리헨션으로

한 줄

  • [len(j) for j in jobs]
  • 「담을 것」이 앞, 「어디서」가 뒤
  • 대괄호라 결과가 리스트인 게 바로 보인다
# [ len(j)      for j in jobs ]
#   └ 담을 것     └ 어디서 꺼내나
# 뒤부터 읽는다: "jobs 에서 j 를 하나씩 꺼내 len(j) 를 담는다"
[len(j) for j in jobs]
터미널
  • [3, 5, 3, 2]

뒤에 if 를 붙이면 걸러진다.

# [ j     for j in jobs   if len(j) >= 4 ]
#   └담을것  └어디서          └거를 조건
[j for j in jobs if len(j) >= 4]
터미널
  • ['프론트엔드']

담는 것이 딕셔너리여도 된다. 검색 결과를 만들 때 이 모양이 계속 나온다.

[{"name": j} for j in jobs[:2]]
터미널
  • [{'name': '백엔드'}, {'name': '프론트엔드'}]

7. 판단 — 참인지 묻기

"서버" in s             # in 은 "안에 있나"를 묻는다
"디자인" in s
3 == 3                  # == 는 "같은가". 값을 넣는 = 와 다르다
터미널
  • True
  • False
  • True

빈 것은 거짓이다. 이 성질을 자주 쓴다.

not []          # 빈 리스트
not ""          # 빈 문자열
터미널
  • True
  • True

8. 자주 만나는 에러 네 가지

이 넷이 대부분이다
화면에 뜨는 것무슨 뜻어디를 보나
IndexError: list index out of range없는 번호를 꺼냈다jobs[99] — 길이를 넘었다
KeyError: '없는키'없는 이름을 꺼냈다딕셔너리 이름 오타
TypeError: ... 'NoneType' has no len()None 을 리스트처럼 썼다함수에 `return` 이 빠졌다
TypeError: can only concatenate str글자와 숫자를 더했다"3" + 3 — f-string 을 쓴다
IndentationError들여쓰기가 안 맞는다for · def 다음 줄 공백 4칸
NameError: name 'x' is not defined없는 이름을 썼다오타이거나, 파이썬을 껐다 켰다

한 장 요약

이 시리즈에 나오는 문법 전부
쓰는 법하는 일
len(x)문자열이면 글자 수, 리스트면 항목 수
s[0] · s[-1]번호로 하나 꺼내기. 0부터, 음수는 뒤에서
s[0:3] · s[:3] · s[3:]구간 꺼내기. 끝 번호는 안 들어간다
f"{x}" · {x:.2f} · {x:3d}문장에 값 넣기와 보여줄 방식
[a, b, c]리스트 — 같은 종류 여럿
리스트.append(x)끝에 하나 붙이기
{"이름": 값} · d["이름"]딕셔너리 — 한 덩어리에 여러 정보
d["새이름"] = 값항목 추가
def f(a, b=기본값): · return함수 만들기. 기본값은 뒤쪽에만
for x in 목록:하나씩 꺼내 반복
enumerate(목록, start=1)번호와 값을 같이
range(0, n, 간격)숫자를 차례로. 끝은 안 들어간다
d.items()딕셔너리를 이름·값 짝으로
[f(x) for x in 목록]컴프리헨션 — 반복문 한 줄
[x for x in 목록 if 조건]거르기
x in y · == · not x판단하기. 빈 것은 거짓

여기 없는 것은 이 시리즈에 나오지 않는다. 클래스, 데코레이터, 제너레이터, async — 전부 필요할 때 배우면 된다.

스스로 해보기

확인 문제 셋
  1. 01

    내 이름으로 문자열을 만들어 앞 두 글자를 꺼낸다

    슬라이싱이 손에 익는 게 이 시리즈에서 제일 많이 쓰인다.

    me = "내 이름을 여기"
    me[:2]
  2. 02

    좋아하는 것 세 개를 리스트로 만들고 길이를 컴프리헨션으로 잰다

    반복문 세 줄로도 해보고 한 줄로도 해본다. 같은 결과가 나오는 것을 확인한다.

    likes = ["...", "...", "..."]
    [len(x) for x in likes]
  3. 03

    함수를 하나 만들되 일부러 return 을 빼본다

    부르면 무엇이 나오나. 거기에 len() 을 씌우면 무슨 에러가 나나. 이 실수를 미리 한 번 해두면 나중에 훨씬 빨리 알아챈다.

1번 — 앞 두 글자 꺼내기충분히 고민해본 뒤 꼭 필요한 경우에만 열어보세요

me[:2]me[0:2] 와 같다. 시작을 비우면 처음부터라는 뜻이다.

끝 번호 2는 들어가지 않는다. 0번과 1번, 두 글자다.

me = "김철수"

me[:2]        # 앞 두 글자
me[-1]        # 마지막 한 글자
me[1:]        # 두 번째부터 끝까지

결과는 차례로 '김철' · '수' · '철수' 다.

2번 — 컴프리헨션으로 길이 재기충분히 고민해본 뒤 꼭 필요한 경우에만 열어보세요

반복문 세 줄과 컴프리헨션 한 줄이 똑같은 결과를 낸다. 둘 다 해보고 확인하는 것이 이 문제의 목적이다.

likes = ["영화", "산책", "커피"]

# 반복문으로 — 빈 리스트를 만들고 하나씩 쌓는다
result = []
for x in likes:
    result.append(len(x))
result                          # [2, 2, 2]

# 컴프리헨션으로 — 같은 일을 한 줄에
[len(x) for x in likes]         # [2, 2, 2]

같은 값이 나오면 성공이다. 컴프리헨션은 새 기능이 아니라 같은 반복문을 짧게 쓴 것이다.

3번 — return 을 빼면충분히 고민해본 뒤 꼭 필요한 경우에만 열어보세요

부르면 아무것도 안 나오고 에러도 안 난다. 파이썬이 조용히 None 을 돌려주기 때문이다.

그걸 리스트인 줄 알고 len() 을 씌우면 그제서야 터진다. 에러가 난 자리와 원인이 있는 자리가 다르다.

def no_return(x):
    x + 1               # 계산만 하고 밖으로 안 내보낸다

no_return(1)            # 화면에 아무것도 안 나온다
print(no_return(1))     # 찍어보면 None

len(no_return(1))       # 여기서 터진다

TypeError: object of type 'NoneType' has no len()

이 에러를 보면 「어딘가에 return 이 빠졌다」를 먼저 의심하면 된다.

정리하면

문자열을 자르고, 값을 문장에 넣고, 리스트와 딕셔너리에 담고, 함수로 묶고, 반복으로 처리한다. 다섯 가지가 전부다.

그중 반복이 가장 많이 나온다. 문서를 조각내는 것도, 조각마다 점수를 매기는 것도, 상위 몇 개를 뽑는 것도 전부 반복이다.

다음 강의부터 이 문법으로 문서를 잘라 검색하는 것을 직접 만든다.

먼저 보는 문법 한 장 — 이 시리즈에 나오는 것만 — 디코드랩(DCODELAB)