변수(Variables)
값을 저장하는 장소
메모리 주소를 가지고 있고 변수에 할당되는 값은 메모리 주소가 가리키는 곳에 저장된다.
기본 데이터 타입(primitive data-type)
정수(integer), 실수(float), 문자열(string), 논리형(boolean)이 있다.
동적 타이핑(dynamic typing)
코드가 실행되는 시점에서 변수의 데이터 타입을 결정한다.
즉, 실행하지 전까지 A라는 변수가 어떤 타입인지 모른다.
코드의 유연함과 편리성이 증가하지만 이로 인해 오류가 발생할 수 있다.
고정소수점(fixed point)
컴퓨터는 2진수로 데이터를 저장한다.
예를 들어 10진수의 14을 2진수로 변환한다면 1110
가 된다.
만약 8bit를 저장할 수 있다면 00001110
로 저장한다.
실수는 정수부와 소수부가 있다.
만약 32bit 실수를 고정 소수점으로 표현한다면 1bit는 부호, 15bit는 정수부, 나머지 16bit는 소수부를 표현한다.
이 방식은 표현할 수 있는 수의 범위가 작다.
부동소수점(floating point)
이 방법은 지수표현식을 이용하며 부호, 지수, 가수 비트를 사용하며 32bit 기준 각각 1, 8, 23비트를 사용한다.
예를 들어 654.32를 2진수로 바꾸면 1010001110.01010001111011
가 된다.
아래와 같이 바꿀 수 있다.
1.01000111001010001111011 * 29
.
지수 비트에 해당하는 값은 100010002
(136=127 + 9)인데 지수의 부호를 나타내기 위해 127을 더하고 2진수로 나타낸다.
가수 비트는 1.01000111001010001111011
에서 맨 앞의 1을 제외한 나머지에 해당한다.
즉, 이를 부동소수점으로 바꾼다면 다음과 같이 바뀐다.
01000100 00100011 10010100 01111011
부동소수점은 정확하게 수를 표현할 수 없으므로 항상 오차가 발생한다.
조건문(conditional statement)
조건에 따라 특정한 동작을 하는 명령문
if
elif
else
를 사용하여 작성할 수 있다.
A == B vs A is B
A == B
는 두 변수에 저장된 값을 비교한다.
A is B
는 두 변수의 메모리 주소를 비교한다.
후자는 같은 객체를 참조하는지 확인하는 방법이다.
반복문(loop statement)
정해진 동작을 반복하는 명령문
for
와 while
loop가 있으며 전자는 정해진 횟수만큼 동작하고 후자도 역시 정해진 횟수만큼 동작할 수 있다.
차이점은 while
은 조건문이 필요하며 몇번 반복할지 모를 때 사용할 수 있다.
while
은 조건문이 True
일 때 동작한다.
# for loop
# 10번의 정해진 횟수만큼 반복한다.
for i in range(10):
print(i)
# while loop
# for loop처럼 정해진 횟수만큼 반복할 수 있다.
i = 0
while i < 10:
print(i)
i += 1
# 예를 들어 i = 1223는 소수이며 i보다 큰 소수를 찾는다고 하자.
# 그럼 i에 1을 더하여 소수인지 확인해보고 아니면 계속 1씩 더하자.
# 그럼 is_prime 함수가 i이 소수인지 확인하고 아니라면 False를 반환한다.
# 이때 while의 조건문이 not is_prime(i)이므로 i가 소수라면 True가 되어 반복문이 동작한다.
def is_prime(num):
# num이 소수이면 True, 그렇지 않으면 False를 반환하는 함수
...
return True
i = 1223
i += 1
while not is_prime(i):
i += 1
반복문에서만 사용할 수 있는 continue
와 break
가 있다.
continue
는 반복문 내 continue
이하의 코드를 건너뛰고 다음 반복으로 넘어간다.
# i가 홀수일 때 출력하며 짝수일 때 continue에 의해 print(i)가 생략된다.
for i in range(10):
if i % 2 == 0:
continue
print(i)
break
는 특정시점에서 반복문을 종료한다.
# i가 0~4일 때 출력되지만 5일 때 반복문을 종료한다.
for i in range(10):
if i == 5:
break
print(i)
함수(function)
함수란 어떤 작업을 하는 코드 덩어리이다.
함수의 수학적 정의를 따른다.
즉, 1개의 어떤 값을 입력하면 1개의 대응값이 존재한다.
함수의 입력 값을 parameter
혹은 argument
라 한다.
string formatting
나는 초등학생입니다.
, 나는 중학생입니다.
, 나는 고등학생입니다.
가 있을 때,
공통인 부분은 나는 ???입니다.
이다.
물음표에 값을 바꿀 수 있다면 효과적일 것이다.
방법에는 3가지가 있다.
%
활용a = "나는 %s입니다." % "초등학생" print(a) b = "나는 %s입니다." % "중학생" print(b) c = "나는 %s입니다." % "고등학생" print(c)
format
함수a = "나는 {}입니다.".format("초등학생") print(a) b = "나는 {}입니다.".format("중학생") print(b) c = "나는 {}입니다.".format("고등학생") print(c)
f string
a = "초등학생" A = f"나는 {a}입니다." print(A) b = "중학생" B = f"나는 {b}입니다." print(B) c = "초등학생" C = f"나는 {c}입니다." print(C)
문자열(string)
한 글자당 1byte의 메모리 공간이 필요하다.
문자열의 각 문자는 각각 메모리 주소를 가지고 있다.
escape characters란 \
로 이루어진 특수한 의미를 가진 문자열이다.
\b
, \n
, \t
, \f
, \\
, \'
등이 있다.
함수의 인자로 전달되는 방식, call by object reference
python의 객체는 두가지로 나눌 수 있는데, mutable과 immutable 객체가 있다.
mutable 객체는 변경할 수 있고 immutable 객체는 변경할 수 없다.
대표적인 mutable 객체는 list
이며, immutable 객체는 tuple
과 int
가 있다.
만약 함수가 mutable 객체를 인자로 받아서 내부에서 이 객체를 변경하는 경우 원본의 객체도 변경된다.
즉, 함수의 객체가 mutable인 경우 call by reference가 된다.
l = [1, 2, 3]
def func(a):
a.append(99)
return
print(l) # [1, 2, 3]
func(l)
print(l) # [1, 2, 3, 99]
immutable 객체는 이와 달리 함수의 인자로 받으면 call by value로 동작한다.
즉, 객체의 값을 복사하여 함수에 넘겨준다.
val = 1
def func(a):
a += 10
print(a)
return
print(val) # 1
func(val) # 11
print(val) # 1
변수의 범위(scope)
지역변수 - 함수 내에서 선언된 변수, 함수 내에서만 사용할 수 있다.
전역변수 - 함수 밖에서 선언된 변수, 어디서나 사용할 수 있다.
만약 전역변수를 함수 내에서 변경을 하고 싶다면 global
을 사용해야 된다.
val = 10
def func():
global val
val += 1
return
print(val) # 10
func()
print(val) # 11
재귀함수(recursive function)
자기 자신을 호출하는 함수로서 종료 조건을 만족하면 멈춘다.
프로그래밍 가이드 라인
함수는 가능하면 짧게 작성하며 이름에 역할과 의도가 명확히 나타나야 된다.
인자로 받은 값을 바꾸지 말자.
예를 들어 함수의 인자를 list
와 같은 mutable 객체를 받는다면 복사하여 사용한다.
원본을 변경하는 실수를 피할 수 있다.
l = [1, 2, 3]
def func(l):
new_list = list(l)
new_list.append(999)
print(new_list)
return
print(l) # [1, 2, 3]
func(l) # [1, 2, 3, 999]
print(l) # [1, 2, 3]
다른 사람의 이해를 돕기 위해 코딩 컨벤션을 숙지하자.