if
조건문, for
반복문, while
반복문정수, 부동소수점, 부울값(True
와 False
), 문자열, 날짜와 시간 등처럼
단일한 값의 자료형을 스칼라 자료형이라 부른다.
반면에 리스트, 튜플, 사전 등은 스칼라 자료형이 아니다.
참고: 문자열은 언어에 따라 스칼라 자료형이 아닐 수도 있다. 예를 들어, C 언어는 문자열을 문자로 이루어진 어레이로 정의되기에 스칼라 자료형이라 말하기 어렵다.
int
¶int
자료형은 임의의 숫자를 다룰 수 있다.
ival = 17239871
ival ** 6 # ival의 6승
26254519291092456596965462913230729701102721
float
¶유리수를 다룬다.
fval = 7.243
과학 표기법도 사용할 수 있다.
fval2 = 6.78e-5
fval2
6.78e-05
나눗셈은 부동소수점으로 계산된다.
3 / 2
1.5
몫은 정수형으로 계산된다.
3 // 2
1
str
¶문자열은 작은따옴표('
) 또는 큰따옴표("
)를 사용한다.
a = '작은따옴표를 사용하는 문자열'
b = "큰따옴표를 사용하는 문자열"
여러 줄로 이루어진 문자열은 삼중 큰따옴표로 감싼다.
c = """
여러 줄에 걸친 문자열은
삼중 큰따옴표로 감싼다.
"""
문자열 자료형은 다양한 메서드를 제공한다.
예를 들어, 문자열이 몇 줄로 이루어졌는가를
확인하려면 count()
메서드를 이용하여
줄바꿈 기호(\n
)가 사용된 횟수를 세면 된다.
c.count('\n')
3
문자열은 앞서 설명한 대로 수정할 수 없는 불변(immutable) 자료형이다.
a = 'this is a string'
a[10] = 'f'
--------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-10-506193ff10e6> in <module> 1 a = 'this is a string' 2 ----> 3 a[10] = 'f' TypeError: 'str' object does not support item assignment
한 번 생성된 문자열은 수정할 수 없지만 새로운 문자열을 생성하는 데에 활용될 수는 있다.
예를 들어, replace()
메서드는 문자열에 사용된 부분 문자열을 다른 문자열로 대체하는
방식으로 새로운 문자열을 생성한다.
b = a.replace('string', 'longer string')
b
변수 a
가 가리키는 값은 변하지 않았다.
a
많은 파이썬 객체를 str()
함수를 이용하여 문자열로 변환할 수 있다.
주의사항: str
은 문자열 자료형을, str()
은 문자열을 반환하는 함수를 가리킨다.
a = 5.6
s = str(a)
type(s)
str
문자열을 리스트, 튜플 등처럼 일종의 순차 자료형, 즉, 순서가 있는 모음 자료형으로 취급할 수도 있다. 따라서 인덱싱, 슬라이싱 기능 등이 모두 사용가능하다.
참고: 인덱싱, 슬라이싱 등에 대해서 앞으로 많이 배울 것이다.
s = 'python'
s[:3]
'pyt'
주의사항: 윈도우 브라우저에서는 역슬래시가 원화 통화기호(₩) 모양으로 보이지만, 동일하게 기능한다.
역슬래시 문자(\)는 특수한 기능을 수행한다.
예를 들어, 줄바꿈을 의미하는 문자 \n
,
탭을 의미하는 문자 \t
등에서 역슬래시가 특수한 기능을 수행한다.
따라서 역슬래시 자체를 문자열에 포함할 때 조심해야 한다.
예를 들어, 아래와 같은 문자열을 사용하고자 한다고 가정하자.
"12\34"
그런데 그냥 아래와 같이 지정하면 다르게 작동한다.
이유는 \3
이 특수한 문자를 표현하도록 역슬래시가 기능하기 때문이다.
(아래 유니코드 설명 참조)
s = '12\34'
print(s)
12
s = '\3'
print(s)
따라서 12\34
로 출력되게 하려면 역슬래시의 기능을 해제해야 하며,
그러기 위해 역슬래시를 두 번 적어주면 된다.
그러면 첫째 역슬래시 뒤에 나오는 역슬래시의 기능을 해제해서 지정한 문자열로 처리된다.
참고: 이처럼 특정 기능을 작동하지 못하도록 하는 것을 영어로 이스케이프(escape)라고 부른다.
s = '12\\34'
print(s)
12\34
그런데 문자열 안에 많은 역슬래시가 포함되어 있다면
이런 방식은 매우 불편하다.
하지만 문자열 앞에 영어 알파벳 r
을 추가하면 간단하게 해결된다.
s = r'this\has\no\special\characters'
print(s)
this\has\no\special\characters
두 문자열을 더하면 두 문자열을 이어서 붙인다.
a = 'this is the first half '
b = 'and this is the second half'
a + b
'this is the first half and this is the second half'
문자열과 정수를 곱하면 해당 정수만큼 복사되어 길어진다.
a * 2
'this is the first half this is the first half '
문자열 템플릿은 문자열 안에 일부 변하는 값을 지정할 수 있도록 선언된 문자열이다.
예를 들어, 아래 템플릿은 세 개의 값을 임의로 지정할 수 있도록 준비되어 있다.
template = '{0:.2f} {1:s}는 {2:d} 미국달러에 해당한다.'
참고: 중괄호 안에 사용된 숫자와 기호의 의미는 다음과 같다.
0:.2f
- format()
메서드의 첫째 인자인 부동소수점이 자리하며 소수점 이하 두 자리까지 표기1:s
- format()
메서드의 둘째 인자인 문자열이 자리하는 자리2:d
- format()
메서드의 셋째 인자인 정수가 위치하는 자리문자열 템플릿에 지정된 수 만큼의 값을 format()
메서드를 이용하여 입력하여
새로운 문자열을 생성할 수 있다.
단, format()
메서드에 사용되는 인자의 순서는 지정된 순서대로 정해져야 한다.
예를 들어, template
변수가 가리키는 문자열 템플릿의 세 위치에 차례대로
부동소수점, 문자열, 정수를 입력해야 하며, 아래와 같이
차례대로 인자로 사용하면 된다.
template.format(4.5560, '아르헨티나 페소', 1)
'4.56 아르헨티나 페소는 1 미국달러에 해당한다.'
참고:
콜론(:
)을 포함하여 그 이후에 해당하는 부분은 입력될 값들의 자료형을 안내하는 역할을 수행한다.
하지만 의무사항은 아니며 다만, 사용되는 값에 대한 정보를 제공하거나
아니면 보다 서식을 갖춘 문자열이 출력하도록 사용된다.
template = '{0} {1}는 {2} 미국달러에 해당한다.'
template.format(4.5560, '아르헨티나 페소', 1)
'4.556 아르헨티나 페소는 1 미국달러에 해당한다.'
format()
메서드를 사용하는 대신에
요즘에는 f-문자열을 보다 많이 사용한다.
이유는 보다 편리한 사용성 때문이다.
f-문자열은 문자열 앞에 영어 알파벳 f를 추가하기만 하면 되며
문자열 안에 변수를 중괄호로 감싸 직접 대입한다.
a = 4.5560
b = '아르헨티나 페소'
c = 1
template = f'{a:.2f} {b:s}는 {c:d} 미국달러에 해당한다.'
template
'4.56 아르헨티나 페소는 1 미국달러에 해당한다.'
여기서도 콜론 부분은 생략해도 된다.
template = f'{a} {b}는 {c} 미국달러에 해당한다.'
template
'4.556 아르헨티나 페소는 1 미국달러에 해당한다.'
유니코드(unicode)는 순전히 키보드만을 이용하여 문자를 표현하는 코드표 모음집이며 파이썬에서 영어 알파벳과 한글을 포함하여 거의 모든 문자를 지원한다. 파이썬 또한 유니코드를 기본적으로 지원한다.
반면에 바이트(bytes)는 문자코드가 컴퓨터가 이해할 수 있는 형태로 변환된 값이다. 유니코드를 바이트로 인코딩(변환, encoding)하는 방식은 일반적으로 UTF-8 방식을 따른다. 반면에 한글에 특화된 인코딩 방식으로 EUC-KR, CP-949 등이 있다. 따라서 사용하는 브라우저에 따라 한글이 깨져서 보이는 경우 언급한 세 가지 인코딩 방식 중 하나로 설정해야 한다.
참고: 요즘은 UTF-8 방식으로 인코딩하는 것을 기본값으로 추천한다.
예를 들어, 아래는 스페인어(Spanish)를 의미하는 스페인 단어 "español"를 가리키는 변수를 선언한다.
val = "español"
val
'español'
UTF-8 방식으로 바이트로 인코딩하면 사람은 알아볼 수 없게 된다.
val_utf8 = val.encode('utf-8')
val_utf8
b'espa\xc3\xb1ol'
인코딩된 값의 자료형은 bytes
이다.
type(val_utf8)
bytes
인코딩 방식을 안다면 유니코드로 디코딩할 수 있다.
val_utf8.decode('utf-8')
'español'
UTF-8 방식이 대세이지만 다른 인코딩 방식도 존재한다는 사실 정도는 상식으로 알고 있어야 한다.
bytes
자료형의 객체는 파일(files) 다루면서 흔하게 접한다.
문자열 앞에 b
를 붙이면 UTF-8 방식으로 인코딩 된 bytes
객체로 취급된다.
bytes_val = b'this is bytes'
bytes_val
b'this is bytes'
UTF-8 방식으로 디코딩하면 유니코드 문자열(str
)을 얻는다.
decoded = bytes_val.decode('utf8')
decoded
'this is bytes'
type(decoded)
str
True
또는 False
의 값으로 계산될 수 있는 값을 부울값(boolean values)이다.
부울값과 관려된 연산자는 논리곱 연산자 and
, 논리합 연산자 or
가 대표적이며,
두 연산자의 기능은 일반적으로 알려진 것과 동일하다.
True and True
True
False or True
True
str()
, bool()
, int()
, float()
는
인자로 들어온 값을 각각 문자열, 부울값, 정수, 부동소수점으로 변환한다.
단, 인자로 사용된 값에 따라 오류가 발생할 수 있다.
s = '3.14159'
fval = float(s)
fval
3.14159
type(fval)
float
int()
함수는 부동소수점에서 소수점 이하를 버리고 정수를 반환한다.
int(fval)
3
int()
함수는 문자열도 직접 정수로 반환한다.
int('334')
334
하지만 문자열이 정수 형식이 아니면 오류가 발생한다.
int(s)
--------------------------------------------------------------------------- ValueError Traceback (most recent call last) <ipython-input-40-2c4720ab420a> in <module> ----> 1 int(s) ValueError: invalid literal for int() with base 10: '3.14159'
bool()
함수는 0에 대해서만 False
를 반환한다.
bool(fval)
True
bool(0)
False
bool(-1)
True
None
값¶None
은 어떤 의미도 없는 값, 소위 널(null)값이며,
문법적으로 NoneType
자료형의 유일한 값이다.
type(None)
NoneType
a = None
a is None
True
b = 5
b is not None
True
None
은 특정 매개변수에 대한 인자가 경우에 따라 추가로 필요할 때를 대비에서 키워드 매개변수의
기본값으로 사용되곤 한다.
예를 들어, 아래 add_and_maybe_multiply()
함수의 셋째 인자는 기본적으로 None
이지만,
경우에 따라 다른 값을 지정하여 사용할 수 있도록 활용되고 있다.
def add_and_maybe_multiply(a, b, c=None):
result = a + b
if c is not None:
result = result * c
return result
키워드 인자를 별도로 지정하지 않으면 지정된 값을 사용한다.
add_and_maybe_multiply(2, 3) # 2 + 3
5
키워드 인자를 별도로 지정하면 그 값을 사용한다.
add_and_maybe_multiply(2, 3, 4) # (2 + 3) * 4
20
datetime
모듈은 날짜와 시간과 관련된 유용한 클래스를 제공한다.
대표적으로 datetime
, date
, time
세 클래스가 포함되며
각각 날짜와시간, 날짜, 시간 정보를 속성으로 갖는다.
from datetime import datetime, date, time
년-월-일-시-분-초 정보를 담은 객체는 아래와 같이 생성한다.
dt = datetime(2021, 3, 2, 17, 5, 1)
datetime
객체는 년-월-일-시-분-초를 각각 따로 제공하는 속성 변수를 갖고 있다.
예를 들어, 일(day) 속성은 아래와 같이 확인한다.
dt.day
2
분(minute) 속성은 다음과 같이 확인한다.
dt.minute
5
날짜 정보만 갖는 date
클래스의 객체로의 변환은 date()
메서드를 이용한다.
dt.date()
datetime.date(2021, 3, 2)
시간 정보만 갖는 time
클래스의 객체로의 변환은 time()
메서드를 이용한다.
dt.time()
datetime.time(17, 5, 1)
일상적으로 사용하는 날짜-시간 표기법으로 변환하려면 strftime()
메서드를 이용한다.
단, 인자로 어떤 포맷(format)을 따를지 지정해야 한다.
예를 들어, 서양식은 24시간 형식을 따르면서, 요일, 달-일-년 시:분
으로 많이 보여준다.
dt.strftime('%A, %m/%d/%Y %H:%M')
'Tuesday, 03/02/2021 17:05'
반면에 한국식은 오전/오후를 구분하여 12시간제를 따르면서, 년-월-일(요일) 시:분
으로 많이 보여준다.
dt.strftime('%Y/%m/%d(%A) %I:%M%p')
'2021/03/02(Tuesday) 05:05PM'
참고: 보다 다양한 포맷(format)에 대한 정보는 datetime 모듈의 공식문서에서 확인할 수 있다.
strptime()
함수는 문자열을 해석하여 datetime
클래스의 객체로 변환한다.
대신에 입력된 문자가 어떤 포맷을 따르는가에 대한 정보를 둘째 인자로 함께 전달해야 한다.
datetime.strptime('20200228', '%Y%m%d')
datetime.datetime(2020, 2, 28, 0, 0)
주의사항: 0초인 경우 굳이 보여주지 않는다.
datetime
클래스의 객체는 불변(immutable)이다.
하지만 문자열의 경우와 비슷하게 특정 값을 이용하여 새로운 datetime
클래스의
객체를 생성할 수는 있다.
예를 들어, replace()
메서드는 년, 월, 일, 시, 분, 초 각각의 값을 다른 값으로 지정하여
새로운 datetime
클래스의 객체를 생성한다.
아래 예제는 분과 초를 모두 0으로 설정하여 새로운 datetime
객체를 생성한다.
dt.replace(minute=0, second=0)
datetime.datetime(2021, 3, 2, 17, 0)
두 datetime
객체의 차(difference)는
일(days)과 초(seconds) 단위로 계산되어 timedelta
클래스의 객체를 반환한다.
dt2 = datetime(2021, 6, 15, 23, 59)
delta = dt2 - dt
delta
datetime.timedelta(days=105, seconds=24839)
type(delta)
datetime.timedelta
실제로 dt + deta == dt2
는 참이된다.
dt
datetime.datetime(2021, 3, 2, 17, 5, 1)
dt + delta == dt2
True
프로그램 실행의 흐름을 제어하는 명령문을 소개한다.
if
조건문for
반복문while
반복문if
조건문¶if
다음에 위치한 조건식이 참이면 해당 본문 불록의 코드를 실행한다.
x = -2
if x < 0:
print("It's negative")
It's negative
주의사항: "It's negative" 문자열 안에 작은따옴표가 사용되기 때문에 반드시 큰따옴표로 감싸야 한다.
조건식이 만족되지 않으면 해당 본문 블록을 건너뛴다.
x = 4
if x < 0:
print("It's negative")
print("if문을 건너뛰었음!")
if문을 건너뛰었음!
경우에 따른 여러 조건을 사용할 경우 원하는 만큼의 elif
문을 사용하고
마지막에 else
문을 한 번 사용할 수 있다.
하지만 else
문이 생략될 수도 있다.
위에 위치한 조건식의 만족여부부터 조사하며 한 곳에서 만족되면 나머지 부분은 무시된다.
if x < 0:
print('음수')
elif x == 0:
print('숫자 0')
elif 0 < x < 5:
print('5 보다 작은 양수')
else:
print('5 보다 큰 양수')
5 보다 작은 양수
참고: 부울 연산자가 사용되는 경우에도 하나의 표현식이 참이거나 거짓이냐에 따라
다른 표현식을 검사하거나 무시하기도 한다.
예를 들어, or
연산자는 첫 표현식이 True
이면 다른 표현식은 검사하지 않는다.
아래 코드에서 a < b
가 참이기에 c/d > 0
은 아예 검사하지 않는다.
하지만 c/d > 0
을 검사한다면 오류가 발생해야 한다.
이유는 0으로 나누는 일은 허용되지 않기 때문이다.
a = 5; b = 7
c = 8; d = 0
if a < b or c / d > 0:
print('오른편 표현식은 검사하지 않아요!')
오른편 표현식은 검사하지 않아요!
실제로 0으로 나눗셈을 시도하면 ZeroDivisionError
라는 오류가 발생한다.
c / d > 0
--------------------------------------------------------------------------- ZeroDivisionError Traceback (most recent call last) <ipython-input-69-2fb2320cb664> in <module> ----> 1 c / d > 0 ZeroDivisionError: division by zero
pass
명령문¶아무 것도 하지 않고 다음으로 넘어가도는 하는 명령문이다. 주로 앞으로 채워야 할 부분을 명시할 때 또는 무시해야 하는 경우를 다룰 때 사용한다.
아래 코드는 x가 0일 때 할 일을 추후에 지정하도록 pass
명령문을 사용한다.
x = 0
if x < 0:
print('negative!')
elif x == 0:
# 할 일: 추추 지정
pass
else:
print('positive!')
삼항 표현식 if ... else ...
를 이용하여 지정된 값을 한 줄로 간단하게 표현할 수 있다.
예를 들어, 아래 코드를 살펴보자.
x = 5
if x >= 0:
y = 'Non-negative'
else:
y = 'Negative'
print(y)
Non-negative
변수 y
를 아래와 같이 한 줄로 선언할 수 있다.
y = 'Non-negative' if x >= 0 else 'Negative'
print(y)
Non-negative
for
반복문¶for
반복문은 리스트, 튜플, 문자열과 같은 이터러블 자료형의 값에 포함된 항목을 순회하는 데에 사용된다.
기본 사용 양식은 다음과 같다.
for item in collection:
# 코드 블록 (item 변수 사용 가능)
continue
명령문¶for
또는 아래에서 소개할 while
반복문이 실행되는 도중에
continue
명령문을 만나는 순간 현재 실행되는 코드의 실행을 멈추고
다음 순번 항목을 대상으로 반복문을 이어간다.
예를 들어, 리스트에 포함된 항목 중에서 None
을 제외한 값들의 합을 계산할 수 있다.
sequence = [1, 2, None, 4, None, 5]
total = 0
for value in sequence:
if value is None:
continue
total += value
print(total)
12
break
명령문¶for
또는 아래에서 소개할 while
반복문이 실행되는 도중에
break
명령문을 만나는 순간 현재 실행되는 반복문 자체의 실행을 멈추고,
다음 명령을 실행한다.
예를 들어, 리스트에 포함된 항목들의 합을 계산하는 과정 중에 5를 만나는 순간
계산을 멈추게 하려면 다음과 같이 break
명령문을 이용한다.
sequence = [1, 2, 0, 4, 6, 5, 2, 1]
total_until_5 = 0
for value in sequence:
if value == 5:
break
total_until_5 += value
print(total_until_5)
13
break
명령문은 가장 안쪽에 있는 for
또는 while
반복문을 빠져나가며,
또 다른 반복문에 의해 감싸져 있다면 해당 반복문을 이어서 실행한다.
예를 들어, 아래 코드는 0, 1, 2, 3으로 이루어진 순서쌍들을 출력한다.
그런데 둘째 항목이 첫째 항목보다 큰 경우는 제외시킨다.
참고: range(4)
는 리스트 [1, 2, 3, 4]
와 유사하게 작동한다.
레인지(range)에 대해서는 잠시 뒤에 살펴본다.
for i in range(4):
for j in range(4):
if j > i:
break
print((i, j))
(0, 0) (1, 0) (1, 1) (2, 0) (2, 1) (2, 2) (3, 0) (3, 1) (3, 2) (3, 3)
리스트, 튜를 등의 항목이 또 다른 튜플, 리스트 등의 값이라면 아래와 같이 여러 개의
변수를 이용하여 for
반복문을 실행할 수 있다.
an_iterator = [(1, 2, 3), (4, 5, 6), (7, 8, 9)]
for a, b, c in an_iterator:
print(a * (b + c))
5 44 119
위 코드에서 a
, b
, c
각각은 길이가 3인 튜플의 첫째, 둘째, 셋째 항목을 가리킨다.
따라서 위 결과는 아래 계산의 결과를 보여준 것이다.
1 * (2 + 3) = 5
4 * (5 + 6) = 44
7 * (8 + 9) = 119
while
반복문¶지정된 조건이 만족되는 동안, 또는 실행 중에 break
명령문을 만날 때까
동일한 코드를 반복실행 시킬 때 while
반복문을 사용한다.
아래 코드는 256부터 시작해서 계속 반으로 나눈 값을 더하는 코드이며, 나누어진 값이 0보다 작거나 같아지면, 또는 더한 합이 500보다 커지면 바로 실행을 멈춘다.
x = 256
total = 0
while x > 0:
if total > 500:
break
total += x
x = x // 2
print(total)
504