입출력과 사칙연산-10단계_곱셈
단계 | 제목 | 설명 | |
---|---|---|---|
1 | 입출력과 사칙연산 | 입력, 출력과 사칙연산을 연습해 봅시다. Hello World! | |
소단계 | 문제번호 | 제목 | |
10 | 2588 | 곱셈 | |
빈 칸에 들어갈 수는? |
문제
(세 자리 수) × (세 자리 수)는 다음과 같은 과정을 통하여 이루어진다.
(1)과 (2)위치에 들어갈 세 자리 자연수가 주어질 때 (3), (4), (5), (6)위치에 들어갈 값을 구하는 프로그램을 작성하시오.
입력
첫째 줄에 (1)의 위치에 들어갈 세 자리 자연수가, 둘째 줄에 (2)의 위치에 들어갈 세자리 자연수가 주어진다.
출력
첫째 줄부터 넷째 줄까지 차례대로 (3), (4), (5), (6)에 들어갈 값을 출력한다.
내 제출
A = int(input())
B = input()
C3 = A * int(B[3])
C2 = A * int(B[2])
C1 = A * int(B[1])
C = A * int(B)
print(C3)
print(C2)
print(C1)
print(C)
결과
오답: 런타임에러(ValueError)
수정 제출
A = int(input())
B = input()
C3 = A * int(B[2])
C2 = A * int(B[1])
C1 = A * int(B[0])
C = A * int(B)
print(C3,C2,C1,C,sep='\n')
결과
정답
오답 이유
파이썬의 경우 문자열 인덱싱의 경우 처음 시작이 0부터 시작하기때문에 0부터 입력을 해주어야 한다. 초기에는 1부터 시작하고, 마지막을 3으로 인덱싱해주었으므로 존재하지 않는 인덱싱 정보를 입력하였으므로 런타임에러가 발생하였다.
사용된 코드 이론
문자열 인덱싱과 슬라이싱
인덱싱(Indexing)이란 무엇인가를 “가리킨다”는 의미이고, 슬라이싱(Slicing)은 무엇인가를 “잘라낸다”는 의미이다. 이런 의미를 생각하면서 다음 내용을 살펴보자.
문자열 인덱싱이란?
>>> a = "Life is too short, You need Python"
위 소스 코드에서 변수 a에 저장한 문자열의 각 문자마다 번호를 매겨 보면 다음과 같다.
Life is too short, You need Python
0 1 2 3
0123456789012345678901234567890123
“Life is too short, You need Python” 문자열에서 L은 첫 번째 자리를 뜻하는 숫자 0, 바로 다음인 i는 1 이런 식으로 계속 번호를 붙인 것이다. 중간에 있는 short의 s는 12가 된다.
이제 다음 예를 실행해 보자.
>>> a = "Life is too short, You need Python"
>>> a[3]
'e'
a[3]이 뜻하는 것은 a라는 문자열의 네 번째 문자 e를 말한다. 프로그래밍을 처음 접하는 독자라면 a[3]에서 숫자 3이 왜 네 번째 문자를 뜻하는지 의아할 수도 있다. 사실 이 부분이 헷갈릴 수 있는 부분인데, 이렇게 생각하면 쉽게 알 수 있을 것이다.
“파이썬은 0부터 숫자를 센다.”
따라서 파이썬은 위 문자열을 다음과 같이 바라보고 있다.
a[0]:'L', a[1]:'i', a[2]:'f', a[3]:'e', a[4]:' ', ...
0부터 숫자를 센다는 것이 처음에는 익숙하지 않겠지만 계속 사용하다 보면 자연스러워질 것이다. 위 예에서 볼 수 있듯이 a[번호]
는 문자열 안의 특정한 값을 뽑아내는 역할을 한다. 이러한 작업을 인덱싱이라고 한다.
문자열 인덱싱 활용하기
인덱싱 예를 몇 가지 더 보자.
>>> a = "Life is too short, You need Python"
>>> a[0]
'L'
>>> a[12]
's'
>>> a[-1]
'n'
앞의 a[0]과 a[12]는 쉽게 이해할 수 있는데 마지막의 a[-1]이 뜻하는 것은 뭘까? 눈치 빠른 독자는 이미 알아챘겠지만 문자열을 뒤에서부터 읽기 위해 마이너스(-) 기호를 붙이는 것이다. 즉 a[-1]은 뒤에서부터 세어 첫 번째가 되는 문자를 말한다. a의 값은 “Life is too short, You need Python” 문자열이므로 뒤에서부터 첫 번째 문자는 가장 마지막 문자 ‘n’이다.
뒤에서부터 첫 번째 문자를 표시할 때도 0부터 세어 “a[-0]이라고 해야 하지 않을까?”라는 의문이 들 수도 있겠지만 잘 생각해 보자. 0과 -0은 똑같은 것이기 때문에 a[-0]은 a[0]과 똑같은 값을 보여 준다.
>>> a[-0]
'L'
계속해서 몇 가지 예를 더 보자.
>>> a[-2]
'o'
>>> a[-5]
'y'
위 첫 번째 예는 뒤에서부터 두 번째 문자를 가리키는 것이고, 두 번째 예는 뒤에서부터 다섯 번째 문자를 가리키는 것이다.
문자열 슬라이싱이란?
그렇다면 “Life is too short, You need Python” 문자열에서 단순히 한 문자만을 뽑아내는 것이 아니라 ‘Life’ 또는 ‘You’ 같은 단어를 뽑아내는 방법은 없을까?
다음과 같이 하면 된다.
>>> a = "Life is too short, You need Python"
>>> b = a[0] + a[1] + a[2] + a[3]
>>> b
'Life'
위 방법처럼 단순하게 접근할 수도 있지만 파이썬에서는 더 좋은 방법을 제공한다. 바로 슬라이싱(Slicing) 기법이다.
인덱싱 기법과 슬라이싱 기법은 뒤에서 배울 자료형인 리스트나 튜플에서도 사용할 수 있다.
위 예는 슬라이싱 기법으로 다음과 같이 간단하게 처리할 수 있다.
>>> a = "Life is too short, You need Python"
>>> a[0:4]
'Life'
a[0:4]가 뜻하는 것은 a 문자열, 즉 “Life is too short, You need Python” 문장에서 자리 번호 0부터 4까지의 문자를 뽑아낸다는 뜻이다. 하지만 다음과 같은 의문이 생길 것이다. a[0]은 L, a[1]은 i, a[2]는 f, a[3]은 e니까 a[0:3]으로도 Life라는 단어를 뽑아낼 수 있지 않을까? 다음 예로 확인해 보자.
>>> a[0:3]
'Lif'
이렇게 되는 이유는 간단하다. 슬라이싱 기법으로 a[시작 번호:끝 번호]를 지정할 때 끝 번호에 해당하는 것은 포함하지 않기 때문이다. a[0:3]을 수식으로 나타내면 다음과 같다.
0 <= a < 3
이 수식을 만족하는 것은 a[0], a[1], a[2]이다. 따라서 a[0:3]은 ‘Lif’이고 a[0:4]는 ‘Life’가 되는 것이다. 이 부분이 문자열 연산에서 가장 혼동하기 쉬운 부분이니 장 마지막의 연습 문제를 많이 풀어 보면서 몸에 익히기 바란다.
문자열을 슬라이싱하는 방법
슬라이싱의 예를 조금 더 보자.
>>> a[0:5]
'Life '
위 예는 a[0] + a[1] + a[2] + a[3] + a[4]와 동일하다. a[4]는 공백 문자이기 때문에 ‘Life’가 아닌 ‘Life ‘가 출력된다. 공백 문자 역시 L, i, f, e 같은 문자와 동일하게 취급되는 것을 잊지 말자. ‘Life’와 ‘Life ‘는 완전히 다른 문자열이다.
슬라이싱할 때 항상 시작 번호가 0일 필요는 없다.
>>> a[0:2]
'Li'
>>> a[5:7]
'is'
>>> a[12:17]
'short'
a[시작 번호:끝 번호]에서 끝 번호 부분을 생략하면 시작 번호부터 그 문자열의 끝까지 뽑아낸다.
>>> a[19:]
'You need Python'
a[시작 번호:끝 번호]에서 시작 번호를 생략하면 문자열의 처음부터 끝 번호까지 뽑아낸다.
>>> a[:17]
'Life is too short'
a[시작 번호:끝 번호]에서 시작 번호와 끝 번호를 생략하면 문자열의 처음부터 끝까지를 뽑아낸다.
>>> a[:]
'Life is too short, You need Python'
슬라이싱에서도 인덱싱과 마찬가지로 마이너스(-) 기호를 사용할 수 있다.
>>> a[19:-7]
'You need'
위 소스 코드에서 a[19:-7]이 뜻하는 것은 a[19]에서부터 a[-8]까지를 말한다. 이 역시 a[-7]은 포함하지 않는다.
슬라이싱으로 문자열 나누기
다음은 자주 사용하게 되는 슬라이싱 기법 중 하나이다.
>>> a = "20010331Rainy"
>>> date = a[:8]
>>> weather = a[8:]
>>> date
'20010331'
>>> weather
'Rainy'
위 예는 문자열 a를 두 부분으로 나누는 기법이다. 숫자 8을 기준으로 문자열 a를 양쪽으로 한 번씩 슬라이싱했다. a[:8]은 a[8]이 포함되지 않고, a[8:]은 a[8]을 포함하기 때문에 8을 기준으로 해서 두 부분으로 나눌 수 있는 것이다. 위 예에서는 “20010331Rainy” 문자열을 날짜를 나타내는 부분인 ‘20010331’과 날씨를 나타내는 부분인 ‘Rainy’로 나누는 방법을 보여 준다.
위 문자열 “20010331Rainy”를 연도 2001, 월과 일을 나타내는 0331, 날씨를 나타내는 Rainy의 세 부분으로 나누려면 다음과 같이 할 수 있다.
>>> a = "20010331Rainy"
>>> year = a[:4]
>>> day = a[4:8]
>>> weather = a[8:]
>>> year
'2001'
>>> day
'0331'
>>> weather
'Rainy'
위 예는 숫자 4와 8로 “20010331Rainy” 문자열을 세 부분으로 나누는 방법을 보여 준다.
지금까지 인덱싱과 슬라이싱에 대해서 살펴보았다. 인덱싱과 슬라이싱은 프로그래밍을 할때 매우 자주 사용하는 기법이니 꼭 반복해서 연습해 두자.
출력 줄바꿈
9.2 줄바꿈 활용하기
이번에는 줄바꿈(개행)을 활용해보겠습니다. 먼저 다음과 같이 print에 값을 여러 개 지정하면 한 줄에 모든 값이 출력됩니다.
>>> print(1, 2, 3)
1 2 3
그럼 print 한 번으로 값을 여러 줄에 출력할 수는 없을까요? 방법은 간단합니다. print의 sep에 개행 문자(\n)라는 특별한 문자를 지정하면 값을 여러 줄로 출력할 수 있습니다.
>>> print(1, 2, 3, sep='\n')
1 # ← 다음 줄로 이동
2 # 2는 새 줄에서 시작, \n은 다음 줄로 이동
3 # ← 새 줄에서 시작
\n은 값을 다음 줄에 출력하게 만드는 제어 문자입니다. 따라서 sep에 \n을 지정하면 1 2 3 사이에 \n이 들어가므로 1을 출력한 뒤 다음 줄에 2를 출력하고 다시 다음 줄에 3을 출력하게 됩니다. 단, \n 자체는 화면에 출력되지 않습니다.
1\n # ← 다음 줄로 이동
2\n # 2는 새 줄에서 시작, \n은 다음 줄로 이동
3 # ← 새 줄에서 시작
참고로 \n도 문자이므로 print에 바로 넣어서 사용할 수도 있습니다. 다음과 같이 문자열 안에 \n를 넣으면 1 2 3은 세 줄로 출력되겠죠? print(1, 2, 3, sep=’\n’)와 결과가 같습니다.
>>> print('1\n2\n3') # 문자열 안에 \n을 사용하여 줄바꿈
1
2
3
‘1\n2\n3’과 같이 \n은 옆에 다른 문자나 숫자와 붙여서 씁니다. 만약 \n 양 옆에 공백을 넣어버리면 공백이 그대로 출력되므로 주의해야 합니다.
참고 | 제어 문자
제어 문자는 화면에 출력되지는 않지만 출력 결과를 제어한다고 해서 제어 문자라 부릅니다. 또한, 제어 문자는 \로 시작하는 이스케이프 시퀀스입니다(부록 47.2 이스케이프 시퀀스' 참조).
- ₩n: 다음 줄로 이동하며 개행이라고도 부릅니다.
- ₩t: 탭 문자, 키보드의 Tab 키와 같으며 여러 칸을 띄웁니다.
- ₩₩: ₩ 문자 자체를 출력할 때는 ₩를 두 번 써야 합니다.