본문 바로가기

Study/AI

[부스트코스 코칭스터디 AI Basic 1기] #1-2. 파이썬 기초 문법

반응형

본 포스트는 '부스트코스 코칭스터디 AI Basic 1기'로 활동하고 '인공지능 기초 다지기' 강의를 들으며 공부한 것을 정리한 글입니다.

 

# 1. Variables

변수의 개요

변수는 가장 기초적인 프로그래밍 문법으로, 데이터(값)를 저장하기 위한 메모리 공간의 프로그래밍 상 이름이다. a=5일 때, a를 변수, 5를 값이라고 한다. 

 

사실 변수는 값을 저장하는 장소로서 메모리 주소를 가지고 있고 변수에 들어가는 값은 메모리 주소에 할당된다. 

 

메모리와 변수

변수가 선언되는 순간 메모리 특정 영역에 물리적인 공간이 할당된다. 변수에는 값이 할당되고 해당 값은 메모리에 저장된다. A=8의 의미는 A라는 이름을 가진 메모리 주소에 8을 저장하라는 것이다.

 

변수명 규칙

- 알파벳, 숫자, 언더스코어(_) 로 선언 가능

- 예약어(reserved word)는 변수명으로 쓸 수 없다.

 

기본 자료형(primitive data types)

파이썬이 처리할 수 있는 data type이다.

유형 설명 예시 선언 형태
수치자료형 정수형 integer 양/음의 정수 1,2,-9 data = 1
실수형 float 소수점 포함 실수 10.2, -9.3 data = 9.0
문자형 string 따옴표에 들어가 있는 문자형   data = 'abc'
data = 'a'
논리/불린 자료형 boolean 참 또는 거짓 True, False data = True

 

type(변수명) 문법으로 변수의 데이터 타입을 알 수 있다. 

 

Dynamic Typing

파이썬은 인터프리터 언어라서 코드 실행시점에 데이터의 Type을 결정한다. 때문에 따로 자료형을 지정해주지 않아도 된다.

 

연산자(Operator)와 피연산자(operand)

연산자에 의해 계산이 되는 숫자들을 피연산자라고 한다. 문자간에서도 +연산이 가능한데 이런 걸 concatenate라고 한다. **은 제곱승, /은 몫 구하기, %은 나머지 구하기 연산자이다. 

참고로 파이썬에서는 C에서 제공하는 ++나 -- 연산이 불가하다.

 

데이터 형 변환

정수형과 실수형 간의 형 변환을 하고 싶을 때 float()와 int() 함수를 사용한다. 다만, a = float(a) 이런 식으로 변환한 것을 변수에 다시 할당해줘야 반영이 된다. 실수형에서 정수형으로 변환 시 소수점은 버린다. 

문자열로 선언된 값도 int(), float() 함수로 수치형으로 변환할 수 있다.

 

List 또는 Array

하나의 변수에 여러 값을 넣는 자료형을 list 혹은 시퀀스 자료형이라고 한다. int, float 같은 다양한 여러 데이터들의 집합을 하나의 변수에 저장할 수 있는 데이터 구조다.

리스트의 특징은 아래와 같다.

- 인덱싱(indexing)

- 슬라이싱(slicing)

- 리스트 연산

- 추가 삭제

- 메모리 저장 방식

- 패킹과 언패킹

- 이차원 리스트

 

인덱싱(indexing)

list에 있는 값들은 주소(offset)를 가지기 때문에 주소를 사용해서 할당되어 있는 element의 값을 호출한다. 앞에서부터 차례대로 0, 1, 2 의 주소를 갖고, 뒤에서부터 차례대로 -1, -2, -3 의 주소를 갖는다.

 

슬라이싱(slicing)

list의 값들을 잘라서 쓰는 것이다. list의 주소 값을 기반으로 부분 값을 반환한다. [시작:끝+1:step]으로 쓴다.

list = ['a', 'b', 'c', 'd', 'e','f', 'g', 'h', 'i']
print(list[0:6], "AND", list[-9:]) # 변수의 0부터 5까지, -9부터 끝까지
print(list[:]) # 변수의 처음부터 끝까지
print(list[-50:50]) # 범위 넘어가면 자동으로 최대 범위 지정
print(list[::2], "AND", list[::-1]) # 2칸 단위로, 역으로 슬라이싱

 

리스트 연산

- concatenation: + 연산자로 두 리스트를 합칠 수 있다.

- *로 리스트를 반복할 수 있다.

- is_in: 어떤 값이 리스트에 존재하는 지 T/F로 확인할 수 있다. ex. 'blue' in color

list1 = ['a', 'b', 'c']
list2 = ['d', 'e', 'f']
print(list1+list2) # 두 리스트 합치기
len(list1) # 리스트 길이
list1[0] = 'k' # 리스트 값 변경
print(list1*2) # 리스트 2회 반복
'a' in list1 # 문자열 'a'가 list1에 존재하는지 여부 반환
total = list1 + list2

- append, extend, insert, remove, del 

list1.append("j") # 리스트에 "j" 추가
list1.extend(["h","l"]) # 리스트에 새로운 리스트 추가
list1.insert(0,"o") # 0번재 주소에 "o" 추가
color.remove("j") # 리스트에 "j" 삭제
del color[0] # 0번째 주소 리스트 객체 삭제(메모리까지)

 

다양한 데이터 타입

파이썬에서는 다양한 데이터 타입을 하나의 리스트에 저장할 수 있다.

 

리스트 메모리 저장 방식

파이썬은 해당 리스트 변수에는 리스트 주소값이 저장된다. 따라서 "="의 의미는 같다가 아니라 메모리 주소에 해당 값을 할당(연결)한다는 의미이다.

a=[5,4,3,2,1]
b=[1,2,3,4,5]
b=a
print(b)
>>> [5,4,3,2,1]
a.sort()
print(b)
>>> [1,2,3,4,5]

따라서 b=a를 하면 a와 b가 같은 메모리 주소를 가르켜서 하나를 바꾸면 다른 하나도 바뀌게 된다.

이런 것을 방지하려면 아래와 같이 작성하면 된다.

b = a[:]

이렇게 하면 리스트 a의 각각의 요소를 복사해서 새로운 공간을 만들어 주고 그것을 b에 연결해준다. 단, 일차원 리스트에서만 가능한 방법이다.

 

패킹과 언패킹

- 패킹: 한 변수에 여러 개의 데이터를 넣는 것

- 언패킹: 한 변수의 데이터를 각각의 변수로 반환

t = [1,2,3]   # 1,2,3을 변수 t에 패킹
a, b, c = t   # t에 있는 값 1,2,3을 변수 a, b, c에 언패킹
print(t, a, b, c)
>>> [1,2,3] 1 2 3

 

이차원 리스트

리스트 안에 리스트를 만들어 행렬(Matrix)을 생성한다.

이차원 리스트를 복사하기 위해서는 copy라는 모듈을 import해서 deepcopy를 사용해야 한다.

import copy
midterm_copy = copy.deepcopy(midterm_score)

 

# 2. Function and Console I/O

함수

어떤 일을 수행하는 코드의 덩어리이다. 인터페이스만 알면 타인의 코드를 사용할 수 있도록 하는 것을 캡슐화라고 한다.

 

parameter vs. argument

- parameter: 함수 정의 시, 함수의 입력 값 인터페이스

- argument: 실제 파라미터에 대입된 값 

사실 잘 구분할 필요 없다.

 

함수 형태

  파라미터 X 파라미터 O
반환 값 X 함수 내의 수행문만 수행 파라미터를 사용하여 수행문만 수행
반환 값 O 수행문 수행 후 결과값 반환 파라미터를 사용하여 수행문을 수행하고 결과값 반환

함수의 return에 print문 작성할 때 주의해야 한다. 아래처럼 작성하면 c에는 아무것도 할당되지 않는다.

def f(x):
	return print(x+10)
    
c = f(10)
c
>>> none

 

Console I/O

input() 함수로 콘솔창에서 문자열을 입력 받는다. 입력 받는 것은 str 형이다. 숫자를 입력 받으려면 float(input())처럼 input문을 형변환 함수로 감싸주어야 한다.

print() 함수로 출력한다.

 

print formatting

프린트 문은 출력의 형식을 지정할 수 있다.

1. %-format

2. format() 함수

3. f-string: 요즘 주로 사용한다. 

print(1,2,3)
print("a"+""+"b"+""+"c")
print("%d %d %d %(1,2,3))
print(" {0} {1} {2}".format("a","b","c"))
print(f"value is {variable}")
print(f'{name:*<20}') # 왼쪽 정렬, 나머지는 *로 채우기

 

실습: 섭씨 to 화씨 프로그램 만들기

print("본 프로그램은 섭씨를 화씨로 변환해주는 프로그램입니다. ")
print("변환하고 싶은 섭씨 온도를 입력해주세요.: ")

cel_value = float(input())
fah_value = ((9/5) * cel_value) + 32

print(f"섭씨온도 : {cel_value:.2f}")
print(f"화씨온도 : {fah_value:.2f}")

 

# 3. Conditionals and Loops

1. 조건문

조건을 나타내는 기준과 명령어가 필요하다. if, else, elif를 통해 구현한다.

여러가지 비교 연산자 중에서 ==, is, 1=, is not이 있는데 이들은 차이가 있다.

is, is not memory의 주소를 비교
(-5~256의 값은 정적메모리에 저장되어 있으므로 이 범위를 넘어가서 비교하면 같은 메모리를 가르키지 않는다고 나옴)
==, != 값을 비교

 

조건 참/거짓을 구분하는 법

컴퓨터는 존재하면 참, 없으면 거짓이라고 판단한다. if "abc":나 if a:은 True이고 if "": 은 거짓이다.

 

all()과 any()

all()은 and 조건과 비슷하다. any()는 or 조건과 비슷하다. 배열 a=[True, False, True, False]와 같은 boolean 값이 저장되어 있을 때, all(a)는 False이고 any(a)는 True이다.

 

삼항 연산자(Ternary operators)

삼항 연산자는 조건문을 사용해서 참일 경우에 명령과 거짓일 경우의 명령을 한 줄에 표현하는 것이다.

'참일_때 if 조건문 else 거짓일_때'로 작성한다.

 

2. 반복문

반복문은 반복 시작 조건, 종료 조건, 수행 명령으로 구헝된다. for, while 등의 명령 키워드를 사용한다.

 

다양한 for 반복문 조건 표현

'for looper in 리스트:'로 작성한다. looper는 리스트에 있는 요소를 하나씩 받아주는 변수이다.

또는 for looper in (0,5): 식으로 작성한다.

 

문자열을 한 자 씩 리스트로 처리 - 시퀀스형 자료형

for i in "abcdefg":

 

각각의 문자열 리스트로 처리

for i in ["americano", "latte", "frafuchino"]:

 

간격을 두고 세기

for i in range(1, 10, 2): # (시작, 끝, step)

 

역순으로 반복문 수행

for i in range(10, 1, -1)

 

while문

조건이 만족하는 동안 반복 명령문을 수행한다.

반복 실행횟수를 명확히 알 때는 for문을 사용하고, 반복 실행횟수가 명확하지 않을 때는 while을 사용한다.

 

break

특정 조건에서 반복을 종료한다.

 

continue

특정 조건에서 남은 반복 명령을 skip한다.

 

else

반복 조건이 만족하지 않을 경우 반복 종료 시 1회 수행한다.

for i in range(10):
	print(i,)
else:
	print("EOP")

단, break로 종료된 반복문은 else block이 수행되지 않는다.

 

# 3. advanced function concept

1. 함수 호출 방식

Call by Value

함수에 인자를 넘길 때 값만 넘긴다.

함수 내에 인자 값 변경 시, 호출자에게 영향을 주지 않는다.

(ex. 함수의 인자 개념)

 

Call by Reference

함수에 인자를 넘길 때 메모리 주소를 넘긴다.

함수 내에 인자 값 변경 시, 호출자의 값도 변경된다.

(ex. C언어의 포인터 개념)

 

 Call by Object Reference

객체의 주소가 함수로 전달되는 방식이다. 파이썬에서는 이 방식을 사용한다.

전달된 객체를 참조하여 변경 시 호출자에게 영향을 주나,

새로운 객체를 만들 경우에 호출자에게 영향을 주지 않는다.

def spam(eggs): # 호출자 eggs
	eggs.append(1) # 기존 객체의 주소값에 [1] 추가
    eggs = [2, 3] # 새로운 객체 생성
    
ham = [0]

spam(ham)

print(ham)
>>> [0,1]

 

2. 변수의 범위(Scoping Rule)

지역변수(local variable)은 함수 내에서만 사용되는 변수이고 전역변수(global variable)은 프로그램 전체에서 사용되는 변수이다. 함수 내에서 전역변수를 선언하고 싶을 때에는 global 키워드를 사용해야 한다.

 

3. 재귀 함수(recursive Function)

자기 자신을 호출하는 함수이다. 점화식과 같은 재귀적 수학 모형을 표현할 때 사용한다. 재귀 종료 조건이 있고, 종료 조건이 될 때까지 함수를 반복해서 호출한다.

def factorial(n):
	if n==1:
    	return 1
    else: 
    	return n * factorial(n-1)

 

4. function type hints

dynamic typing은 처음 함수를 사용하는 사용자가 interface를 알기 어렵다는 단점이 있다. 때문에 type에 대한 힌트를 제공하기 위해 다음과 같이 코드를 작성할 수 있다.

def do_function(var_name: var_type) -> return_type:
	pass
    
# ex.
def type_hint_ex(name: str) -> str:
	return f"Hello", {name}"

 

5. function docstring

파이썬 함수에 대한 상세스펙을 사전에 작성하여 함수 사용자의 이해도를 향상해주는 것이다.

함수명 아래에 따옴표 세 개("""나 ''')로 docstring 영역을 표시한다.

def kos_root():
	"""Return the pathname of the KOS root directory."""
    global_kos_root
    if _kos_root: return _kos_root

주로 아래와 같은 형식을 가진다. vs에서는 extension을 통해서 편리하게 작성할 수 있도록 지원하고 있다.

"""
Args:
	x (int): [description]
    y (int): [description]
    
Returns:
	int: [description]
"""

 

6. 함수 작성 가이드 라인

함수는 가능하면 짧게(최소 단위의 기능) 작성하는 것이 좋다. 또한 함수 이름에 함수의 역할, 의도가 명확히 드러나면 좋다. 주로 'def V_O():' 형태로 '역할+목적어'로 표현한다.

인자로 받은 값 자체를 바꾸지 않는 것이 좋다. [:]를 통해 복사를 해서 임시변수를 선언하고 사용한다.

공통적으로 사용되는 코드, 복잡한 수식이나 조건을 식별 가능한 이름으로 바꿀 때에 함수를 만드는 것이 좋다.

 

# 4. 좋은 코드를 작성하기 위해서

사람들이 서로의 코드를 잘 이해하기 위해서 코딩 컨벤션이 존재한다. 팀 혹은 프로젝트마다 코딩 컨벤션을 맞추는 것이 좋다.

 

"flake8" 모듈로 보기 좋은 코드를 작성했나 체크할 수 있다. cmd에 'conda install -c anaconda flake8'로 모듈을 설치하고 'flake8 <파일명>'을 하면 고쳐야 할 사항을 알 수 있다.

 

최근에는 "black" 모듈을 활용하여 pep8 like 수준을 준수한다. black을 사용하면 알아서 pep8에 맞추어 코드를 사정해준다. 마찬가지로 cmd에 'black codename.py'를 입력하면 된다.

반응형