PYTHON

파이썬 입력과 형변환 — 20을 넣었는데 201이 나오는 이유(INPUT)

PANCO_IT
#파이썬#python#input#형변환#int#float#ValueError#파이썬기초#파이썬독학

노트북 키보드 위에서 타이핑하는 두 손

이미지 출처: Wikimedia Commons, Simon Hattinga Verschure · CC0

이 코드는 왜 내년 나이를 201이라고 할까요. 지난 편 자기소개 카드에 "나이를 직접 입력받자"는 기능 하나를 붙인 것뿐인데, 결과가 이상합니다.

증상 — 20을 넣었는데 내년 나이가 201
age = input("나이를 입력하세요: ")
print(f"내년에는 {age + 1}살이 됩니다.")

이 예제는 키보드 입력을 씁니다. 실행창 아래 STDIN 칸에 미리 넣어 둔 값(20)을 바꿔 가며 실행해 보세요.

📱 코드 실행(실습)은 태블릿·PC에서 이용할 수 있어요. 모바일에서는 위 코드를 눈으로 따라가며 확인하세요.

실행창을 열면 아래쪽 STDIN 칸에 20이 미리 들어 있습니다. 그대로 실행하면 에러가 납니다. 에러 문장을 읽기 전에, 아래 코드로 같은 증상을 더 또렷하게 볼 수 있습니다.

증상을 더 또렷하게 — 글자끼리는 이어 붙는다
age = input("나이를 입력하세요: ")
print(age + "1")      # 20을 넣으면 201이 찍힙니다
print(type(age))       # 정체를 확인해 봅니다

이 예제는 키보드 입력을 씁니다. 실행창 아래 STDIN 칸에 미리 넣어 둔 값(20)을 바꿔 가며 실행해 보세요.

📱 코드 실행(실습)은 태블릿·PC에서 이용할 수 있어요. 모바일에서는 위 코드를 눈으로 따라가며 확인하세요.

STDIN의 20을 그대로 두고 돌리면 201이 나오고, 그 아래 <class 'str'>이 찍힙니다. 오늘은 이 한 줄이 범인을 가리킵니다. 용의자를 하나씩 지워 보겠습니다.

용의자 1 — 키보드가 숫자를 못 알아본다?

아닙니다. 키보드는 20을 정확히 보냈습니다. 문제는 그다음입니다. 파이썬의 input()키보드로 들어온 것을 무조건 글자(str)로 돌려줍니다. 숫자를 쳐도, 소수를 쳐도, 아무것도 안 치고 엔터만 눌러도 전부 글자입니다. 20을 치면 "20"이 되어 상자에 들어갑니다. 따옴표가 붙은 채로요.

키보드로 20을 치면 input()이 "20"이라는 글자로 받아 상자에 넣고, 그래서 age + 1에서 TypeError가 나는 흐름

키보드 → input() → 상자까지 값이 이동하는 동안 한 번도 숫자가 된 적이 없습니다. 상자에 든 것은 "20"이라는 글자입니다.

지난 편에서 "저는 " + 20이 TypeError를 냈던 것을 기억하시면, 첫 번째 실행창의 에러도 같은 이유입니다. 글자 상자 age에 숫자 1을 더하려 했으니까요. 두 번째 실행창에서는 "1"이 글자라서 에러 없이 이어 붙어 "201"이 됐습니다. 파이썬에서 글자에 +는 덧셈이 아니라 이어 붙이기입니다.

용의자 2 — 그럼 input()이 잘못 만들어진 것?

이것도 아닙니다. input()이 글자만 돌려주는 데는 이유가 있습니다. 키보드로는 이름도, 나이도, 주소도 들어옵니다. 파이썬이 "이건 숫자 같으니 숫자로, 저건 글자니 글자로"를 멋대로 정하면 010-1234-5678 같은 전화번호가 뺄셈이 되어 버립니다. 그래서 파이썬은 판단을 하지 않고 전부 글자로 넘긴 뒤, 숫자로 쓸지는 프로그래머가 정하게 둡니다.

진범 — "글자를 숫자로 바꾸는 단계"가 빠졌다

그 정하는 도구가 int()float()입니다. int("20")은 글자 "20"을 정수 20으로, float("3.5")는 글자 "3.5"를 실수 3.5로 바꿔 줍니다. 지난 편에서 str()로 숫자를 글자로 바꿨던 것의 반대 방향입니다.

고친 코드 — int()로 글자를 숫자로 바꾼 뒤 계산
age_text = input("나이를 입력하세요: ")   # 여기까지는 글자
age = int(age_text)                         # 글자를 정수로 바꿔 새 상자에
print(f"내년에는 {age + 1}살이 됩니다.")    # 이제 덧셈이 됩니다
print(type(age_text), type(age))

이 예제는 키보드 입력을 씁니다. 실행창 아래 STDIN 칸에 미리 넣어 둔 값(20)을 바꿔 가며 실행해 보세요.

📱 코드 실행(실습)은 태블릿·PC에서 이용할 수 있어요. 모바일에서는 위 코드를 눈으로 따라가며 확인하세요.

STDIN이 20인 채로 실행하면 내년에는 21살이 됩니다.가 나오고, 마지막 줄에 <class 'str'> <class 'int'>가 찍힙니다. 상자가 두 개인 것을 눈여겨보세요. int()는 원래 글자를 고치는 게 아니라 숫자로 된 새 값을 만들어 돌려줍니다. 그래서 보통은 이렇게 한 줄로 줄여 씁니다.

age = int(input("나이를 입력하세요: "))

안쪽 input()이 먼저 실행되어 글자를 받고, 바깥 int()가 그것을 숫자로 바꿔 age에 넣습니다. 괄호가 겹칠 때는 안쪽부터 실행된다고 읽으면 됩니다.

재발 방지 — 어떤 글자가 숫자가 되고, 어떤 글자가 안 되나

int()가 만능은 아닙니다. 숫자 모양이 아닌 글자를 넣으면 이번엔 ValueError가 납니다. 실행창의 STDIN 값(처음엔 3.5가 들어 있습니다)을 바꿔 가며 직접 확인해 보세요.

실험 — STDIN을 20, 3.5, 스무살, (빈칸)으로 바꿔 가며 실행
text = input("숫자를 입력하세요: ")
print(repr(text))          # 받은 글자를 따옴표째 보여줍니다
number = int(text)         # 여기서 실패하면 ValueError
print(number * 2)

이 예제는 키보드 입력을 씁니다. 실행창 아래 STDIN 칸에 미리 넣어 둔 값(3.5)을 바꿔 가며 실행해 보세요.

📱 코드 실행(실습)은 태블릿·PC에서 이용할 수 있어요. 모바일에서는 위 코드를 눈으로 따라가며 확인하세요.

  • 20'20'이 찍히고 40이 나옵니다.
  • 3.5ValueError: invalid literal for int() with base 10: '3.5'. int()는 소수점 있는 글자를 받지 않습니다. 이럴 땐 float(text)를 씁니다.
  • 스무살 → 같은 ValueError. 숫자 모양이 아니니 당연합니다.
  • 아무것도 안 치고 엔터 → ''(빈 글자)가 찍히고 ValueError. 빈 입력도 글자라서 int("")가 실패합니다.

int()와 float() 변환기에 들어가는 입력 여섯 가지 — "20"·"3.5"·"20"은 통과, "3.5"를 int에·"스무살"·"3,5"·빈 글자는 ValueError

변환기가 받는 글자 모양은 정해져 있습니다. int()는 정수 모양만, float()는 마침표 소수점까지. 쉼표, 단위, 빈칸은 둘 다 거부합니다.

float()는 조금 더 너그럽습니다. float("20")도 되고(결과는 20.0), float("3.5")도 됩니다. 대신 3,5처럼 쉼표를 찍으면 실패합니다. 소수점을 쉼표로 적는 나라도 있지만 파이썬은 마침표만 소수점으로 읽습니다. 그리고 float("3.5")를 정수로 만들고 싶으면 int(float("3.5"))처럼 두 번 감쌉니다. 안쪽에서 3.5가 되고 바깥에서 소수점을 잘라 3이 됩니다. 반올림이 아니라 잘라내기라는 점은 다음 편들에서 다시 나옵니다.

ValueError가 났을 때 프로그램이 죽지 않게 막는 방법(try)은 PYTHON1 뒷부분에서 배웁니다. 지금은 "어떤 입력이 실패하는지"를 아는 것까지가 목표입니다.

확인 사살 — 두 값을 받아 더하기

오늘 배운 것을 한 번에 쓰는 코드입니다. STDIN에 34가 두 줄로 들어 있습니다. input()은 한 번 부를 때마다 한 줄씩 가져갑니다.

두 수를 입력받아 더하기 — STDIN에 3 과 4 를 두 줄로
a = int(input("첫 번째 수: "))
b = int(input("두 번째 수: "))
print(f"{a} + {b} = {a + b}")
print(f"{a} / {b} = {a / b}")     # 나눗셈은 결과가 실수(float)가 됩니다

이 예제는 키보드 입력을 씁니다. 실행창 아래 STDIN 칸에 미리 넣어 둔 값(3 ⏎ 4)을 바꿔 가며 실행해 보세요.

📱 코드 실행(실습)은 태블릿·PC에서 이용할 수 있어요. 모바일에서는 위 코드를 눈으로 따라가며 확인하세요.

3 + 4 = 73 / 4 = 0.75가 나오면 성공입니다. int()를 지우고 다시 돌리면 첫 줄이 3 + 4 = 34가 되는 것도 꼭 한 번 보세요. 오늘 글 전체가 그 한 줄에 들어 있습니다.

여기서 다들 한 번 넘어지는 곳이 하나 더 있습니다. input("나이: ")의 괄호 안 글자는 안내 문구일 뿐이고 결과에 포함되지 않습니다. input()이 돌려주는 것은 사용자가 친 글자뿐입니다. 안내 문구를 화면에 찍는 것과 값을 받는 것을 한 줄에서 같이 하는 것이지, 안내 문구가 값에 붙는 게 아닙니다.

되감기

상황결과이유
input()으로 20을 받음"20" (str)키보드 입력은 전부 글자
"20" + 1TypeError글자에 숫자를 더할 수 없음
"20" + "1""201"글자끼리 +는 이어 붙이기
int("20") + 121글자를 정수로 바꾼 뒤 덧셈
int("3.5")ValueError정수 모양이 아님 → float()
int("")ValueError빈 입력도 글자

오늘 배운 것, 문제로 확인

미니 퀴즈

OX 3문제 + 4지선다 3문제


포켓코딩(PYTHON1) 4편 · 3편(파이썬 변수)에서 이어집니다. 예제 코드는 강사 개인 GitHub 저장소의 연습 문제를 바탕으로 다시 썼습니다. 다음 편: 파이썬 연산자 — 나눗셈이 셋인 이유(/, //, %).

PANCO_IT

IT 지식을 정리하는 개발자

관련 글