반응형

기록 배경

회사에서 개발을 위한 Ubuntu 가 설치된 PC를 주지 않아서 기존에 있는 Windows를 날리기는 라이선스 비가 아까워서 WSL 로 Ubuntu 22.04 를 설치한다음에 jupyter notebook을 실행을 해보는데, 흔히 알려져 있는 jupyter notebook 명령어를 먹지 않더라...

살펴보니 jupyter 명령어가 체계가 개편된 듯 해서 모듈을 살펴보니 notebook 모듈이 별도로 있더라. 그래서 notebook 모듈로 실행하니 익숙한 화면이 보이게 되더라.

해결방법

python 모듈 notebook 를 실행하자.

python3 -m notebook

만약 이래도 실행이 안된다면, jupyter-core 모듈을 설치한뒤에 시도를 해보자.

반응형

'Python > Jupyter' 카테고리의 다른 글

[Jupyter]OpenCV로 끊김이 적은 동영상 재생  (0) 2019.07.08
반응형

개요

실제로는 독립적인 코드 조각을 의미하기도 한다. 프로그래밍 언어에서 특정한 동작을 독립적으로 정의하고 해당 코드를 호출하기 위해 만들어진 개념이다. C 이후에 만들어진 대부분의 프로그래밍 언어에는 존재한다.

코드를 작성할 때 마다 처음부터 작성하는 방법도 있지만, 누군가가 작성해 놓은 코드를 사용 할 경우 함수 형태로 사용하거나 작성하기도 한다.

정의와 호출

어떠한 동작을 할 것인지 def 키워드로 함수를 정의한다. 이미 정의 되어 있는 함수는 함수 이름으로 호출하여 사용한다. 키워드 def는 define에서 따온 것을 추측할 수 있다. 함수명 뒤에는 소괄호로 열고 닫고 마지막으로 코드블록의 시작을 알리는 콜론을 해준을 해준 다음에 들여쓰기로 함수에 해당하는 코드를 작성할 수 있다.

def hello():
    print("hello world")

hello()
# hello world

위의 예제 기준으로 설명하면 hello 는 함수명이 된다. 처음 입문자가 헷깔리는 것이 함수를 정의할 때는 코드가 동작하지 않는다. 실제로 동작하는 것은 함수가 호출 될 때이다. 함수가 호출될 때는 소괄호를 열고 닫아야 한다.

입력 파라미터

입력 파라미터를 입력 인자라고 말하기도 한다(반만 영어인 용어). 함수를 정의할 때 동작시 값을 입력 받을 수 있도록 할 수 있다. 앞의 함수의 예시는 입력 파라미터가 없기 때문에 공란으로 둔 것이다. 입력 파라미터가 있는 함수를 정의하기 위해서는 함수명의 뒤에 오는 소괄호에 함수내에서 변수로 사용할 값을 넣어주면 된다. 만약 입력 파라미터가 2개 정의 되어 있는데, 함수 호출시 입력 파라미터의 수가 맞지 않으면 에러를 발생하고 함수의 코드블록이 실행되지 않는다.

def add(a, b):
	print(a + b)

add(1, 2)
# 3
add(1)
# Error

함수를 정의할 때 정의된 입력 파라미터를 반드시 전부 사용해야 한다는 의무는 없다. 하지만 호출할 때는 default 값이 정해져 있는 것이 아니라면 반드시 정의된 입력 파라미터의 수가 맞아야 한다.

우리가 이전 부터 종종 사용한 print()도 사실 함수이다.

default 값

함수의 입력 파라미터에 대해서 default 값을 정의 할 수 있다. default 값은 해당 입력 파라미터가 없는 경우 미리 정의 되어 있는 상수로 입력 파라미터 값을 사용한다.

default 값이 있는 입력 파라미터는 default 값이 없는 입력 파라미터의 오른쪽에 정의 되어야 한다. 참고로 입력 파라미터가 있는 함수의 호출 과정은 마치 중학교 수학과정의 수학의 함수기호를 사용하는 것과 비슷하다.

def add(a, b = 1):
    print(a + b)

add(1, 2)
# 3

add(1)
# 2

add()
# Error

def diff(a=10, b):
    print(a + b)
# Error

반환

반환이라는 명칭은 C 에서 return 키워드를 통해서 함수에 있는 코드블록의 실행 결과를 호출한 위치에 값을 주는 개념으로 사용되었다. 이는 다른 언어에서도 대부분 동일하게 동작하고 파이썬도 마찬가지다. 이는 함수를 통해서 어떠한 결과를 얻었다는 느낌으로 사용된다.

반환되는 값을 있을 수도 있고 없을 수 도 있다. 함수의 코드블록이 전부 실행되면, 함수 코드블록내에서만 사용한 변수들은 다른 코드블록(보통 외부)에서 접근을 할 수 없다. 하지만 반환 값(리턴되는 값)은 함수 코드블록 밖으로 내보내는 것이고, 그 결과 코드상 함수가 호출된 위치에 반환된 값이 있는 것과 같은 결과가 된다.

def add(a, b):
    return a + b

result = add(1, 2)
# result = 3

result + 4 == add(3, 4)
# True

파이썬에서 독특한 문법으로 반환되는 값이 복수가 될 수 있다. 이렇게 복수로 반환 할 경우 기본적으로 튜플(Tuple)로 묶여서 반환 된다(여기서 독특하다는 이유는 대부분 언어에서는 이렇게 반환되지 않기 때문이다).

함수의 반환 값을 바로 대입할 때 반환 값의 수와 동일한 개수의 변수를 정의 하면 튜플의 원소가 각각 변수에 대입된다.

def minMax(a, b, c):
    minVal = min(a, b, c)
    maxVal = max(a, b, c)
    return minVal, maxVal

results = minMax(1, 2, 3)
print("results:", results)
# results == (1, 3)

minVal, maxVal = minMax(1, 2, 3)
print("(min, max):", minVal, maxVal)
# minVal == 1
# maxVal == 3

함수 내에서 return 키워드가 오게 되면, 함수는 해당 값을 반환하고 함수의 실행을 종료한다. 만약 함수내에 반복문을 실행중이라도 return 키워드를 만나면 반복문의 코드 블록을 포함해서 함수가 종료된다.

words = ["hello", "papa", "its", "me"]
def find(words, keyword):
    index = 0
    for itWord in words:
        if itWord == keyword:
            return index
        index += 1
    return -1

index = find(words, "papa")
print("index:", index)
# index == 1

index = find(words, "what")
print("index:", index)
# index == -1

만약 함수 정의에서 return 키워드를 사용하지 않으면 반환값이 없게 된다. 반환값이 없는 함수를 호출하여 변수에 대입을 하면 None이 대입됨을 알 수 있다. 정확히는 반환값이 없는 것이 아니라 default로 None이 반환되고 있는 것이다.

def diff(a, b):
    print(a - b)

result = diff(1, 2)
print("result:", result)
# result == None

내장 함수

함수 문법에 대한 기초를 이해하고 나면, 한가지 거슬리는 것이 있을 것이다. 바로 화면에 출력하는 print()라던가 예시에 있는 min(), max() 같은 것말이다. 이는 python에서 미리 정의가 되어 있는 함수들이다.

별도로 정의 하지 않았지만, python 자체적으로 바로 사용하는 함수들을 내장 함수라고 부른다. 내장 함수들은 자주 사용되며 코드의 질을 높이는 유용한 것들이 많다. 이에 대해서는 나중에 다시 다루도록 하자

글로벌 변수

함수 등 특정 블록이 아닌 가장 밖에 있는 변수를 글로벌 변수 혹은 전역 변수라 부른다. 함수에서 입력 파라미터 외에 글로벌 변수에 대해서 접근이 가능하다. 하지만, 함수에서 해당 값을 수정하기 위해서는 global 키워드를 사용해야 한다.

gVal = 1

def aFunc1():
    print(gVal)

def aFunc2(a1):
    gVal = a1

def aFunc3(a1):
    global gVal
    gVal = a1

aFunc1()
# 1

aFunc2(3)
# Error

aFunc3(3)
aFunc1()
# 3

특별한 경우를 제외하고 글로벌 변수를 수정하는 것은 바람직하지 않다. 이는 프로그램이 복잡하게 되었을 경우 해당 변수를 어디서 참조하여 영향을 받을지 알 수 없기 때문이다. 이 때문에 별도의 global 키워드를 사용해서 global 변수를 수정하도록 설계되었고, 이를 통해 함수의 코드블록 내에서 글로벌 변수를 수정하는지를 확인하기 쉬워졌다.

반응형

'Python > 배경이 있는 파이썬' 카테고리의 다른 글

반복문(while, for)  (0) 2024.05.11
코드 블록, 조건문(if)  (1) 2024.05.01
불(bool)과 연산  (0) 2024.04.29
딕셔너리(dict)  (0) 2024.04.29
튜플(Tuple)  (1) 2024.04.27
반응형

개요

반복문은 while문과 for 문이 있다. while문은 조건식을 기분으로 while문에 해당되는 코드 블록을 반복 실행을 할지 여부를 따진다. for 문은 순차적으로 접근이 가능한 값으로 부터 모두 접근할때까지 for문에 해당되는 코드 블록을 반복해서 실행한다.

논리적으로 생각해 보면 while 문이나 for 문은 if 문 처럼 조건식을 사용한다. 다만, 분기를 나누느냐 반복을 하느냐의 차이가 있을 뿐이다.

while

while 키워드로 시작하는 문장의 조건식의 결과가 True 이면 해당 코드 블록을 실행하고 False 면 코드 블록을 실행하지 않는다. 다만, 해당 코드 블록을 전부 실행한 이후 벗어나기 전에 while 문장으로 다시 돌아오는 원리로 동작한다. 만약 처음 부터 조건식이 False 라면 해당 코드브록은 if문처럼 실행하지 않고 건너 뛴다.

# 1부터 5까지 더하기
maxValue = 5
result = 0
value = 1
while maxValue > value:
	result = result + value
	value = value + 1
print("result:", result)

위험한 반복문

다음 코드는 절대로 하지 말아야 하는 코드다. 과거의 컴퓨터나 저수준 환경의 컴퓨터에서는 저런 코드를 실행하면 cpu 칩이 타거나 과열되어 멈추는 현상이 발생된다. 현재는 OS상에서 의도적인 무한 while문을 경고로 강제 종료하는 경우도 있지만, 강제 종료가 되지 않는 경우 시스템상 cpu 점유율을 차지하면서 아예 컴퓨터가 느려지면서 멈출 수 도 있다.

# 하지말아야 할 짓
while True
	pass

for

for 키워드는 in 과 함께 사용된다. for 와 in 사이에는 for문에 해당하는 코드 블록에서 사용할 변수명(혹은 복수의 변수명), in 뒤에는 복수형 자료형으로 구성된다. 아래의 예시를 보면 iterator 라는 변수가 있는데, 실제로 iterator라고 부른다. 초기 iterator는 마땅한 번역이 없어서 반복자라고 불리기도 했으나 오늘날에는 그냥 그대로 부르고 개념적으로 다음 값을 리턴할 수 있는 객체라 부른다.

for iterator in [1, 2, 3]:
    print(iterator)
# 1
# 2
# 3

 그러나 실제로는 for문에 해당되는 코드 블록내에서 사용되는 임시 변수라고 보는 것이 적절하고 실질적으로는 문법상 iterator를 이 임시 변수에 대입한 것이라고 보는게 낫다. 왜냐면 코드 블록 내에서 iterator에 다른 값을 대입하는 것이 가능하다. 하지만 이 iterator가 정확히 객체라면 대입시 이 for문은 망가져야 한다. 그러나 문제 없이 계속 실행되니 실질적인 iterator 즉, 객체는 손을 못 대게 막혀 있고 복제 버전만 임시 변수에 대입해서 사용하고 있는 것이다.

그리고 이 iterator를 생성할 수 있는 자료형을 iterable 로 구분한다. list, 뒤에 나올 range() 같은 함수들이 있다.

for문의 반복이 멈추는 조건은 iterator 가 None 즉, 더이상 줄 값이 없을 때 조건문 처럼 for문의 코드 블록을 스킵하게 된다.

 대략적인 동작 방식만 보면 while 문과 달리 조건식이 없는 것 같지만, 내부적으로는 iterator 라는 변수의 값이 비어 있는지를 따져서 코드 블록을 실행할지 여부를 결정한다. 이는 오랫동안 프로그래머들이 실무에서 자주 사용하는 패턴을 단순화 했기 때문이다. 때문에 오래된 언어인 C, C++, Java의 기본 for 문과는 다른 동작을 하는 것 처럼 보인다.

range()

range() 함수는 내장형 함수이다. 호출할 때마다 주어진 범위내의 값을 순차적으로 반환하는 함수이다. 입력 받는 숫자의 개수에 따라 동작 달라진다. 간단한 예시는 다음과 같다.

# 0부터 5까지 더하기
result = 0
for i in range(6):
    result = result + i
print("result:", result)
# 1부터 5까지 더하기
result = 0
for i in range(1, 6):
    result = result + i
print("result:", result)
# 1부터 10까지 홀수만 더하기
result = 0
for i in range(1, 11, 2):
    result = result + i
print("result:", result)

해당 함수는 프로그래머의 오랜 경험상 for문을 실무에서 많이 사용하는 방식으로 변경된 것이다. 따라서 C나 C++의 기본 for문와 방식이 다르다. 하지만, 레거시 for문 처럼 정수를 순차적으로 반복하는 동작이 필요하여 range() 같은 함수가 그 역할을 하고 있다.

for문과 관련된 함수들이 이외에도 있으나 함수에 대해서 먼저 공부하고 나서 다시 다루게 될 것이다.

반복문 관련 키워드

반복문에서 조건문과 조합하여 사용할 수 있는 키워드가 있다.

break

해당 키워드를 만나면 실행중인 반복문의 코드 블록에서 즉시 빠져나와서 반복문의 코드 블록 이후의 코드를 실행한다. 보통 조건문을 조합해서 사용한다.

value = 0
while True:
	if value > 10:
		break
	value = value + 1
print("value:", value)

continue

해당 키워드를 반복문내에서 만나면 반복문에 해당하는 코드블럭의 조건문이 시작하는 위치부터 실행을 한다. 보통 조건문과 같이 조합하여 사용한다. continue 키워드 뒤의 반복문 블록은 실행하지 않고 반복문의 조건식에 해당하는 위치에서 다시 실행한다. for 문의 경우 다음 iterator 를 받게된다.

value = 0
while value < 10:
	value = value + 1
	if value % 2 == 1:
		continue
	print("value:", value)

 

반응형

'Python > 배경이 있는 파이썬' 카테고리의 다른 글

함수(function)  (0) 2024.05.24
코드 블록, 조건문(if)  (1) 2024.05.01
불(bool)과 연산  (0) 2024.04.29
딕셔너리(dict)  (0) 2024.04.29
튜플(Tuple)  (1) 2024.04.27
반응형

개요

조건문은 조건에 따라서 코드블록을 실행할지 말지를 결정한다. 덕분에 조건문으로 실행되는 소스 코드의 실행 분기를 나눌 수 가 있다. 조건문의 문법 키워드는 if, elif, else 키워드로 구성 된다. if, elif 뒤에 조건식이 오고 해당 줄에서 마지막에 :(콜론)이 온다음에 코드 블록을 작성하면 된다. else 의 경우 조건식 없이 :(콜론)으로 끝난다.

코드블록

일종의 코드 덩어리 혹은 구간으로 본다. C 와 같은 오래된 프로그래밍 언어에서는 코드 스택이라고도 한다. 파이썬에서는 들여쓰기로 구분을 한다. 들여쓰기 칸수는 2칸을 쓰거나 4칸을 사용할 수 있다. 파이썬 재단에서는 4칸 들여쓰기로 코드 블록을 구분하는 것을 권장한다. 2칸 들여 쓰기는 주로 구글에서 사용하고 있다.

코드 블록 안에 또 다른 코드 블록을 만들 수 도 있다. 다만, 파이썬에서는 단독으로 코드 블록을 만들 수는 없다. 반면 다른 중괄호로 코드 블록을 구분하는 언어들은 독립적으로 코드 블록을 만들 수 있다.

원칙적으로 코드 블록내에 새로운 변수를 정의 할 경우 코드 실행 흐름상 해당 코드 블록을 벗어나면 메모리에서 해당 변수를 제거한다. 다만 편의상 몇가지 예외가 있는데, for 문의 경우 코드 블럭을 벗어나도 바로 제거하지 않는다.

문법

if 키워드는 첫 조건문이며, if 다음에 오는 조건식이 True 경우 해당 if 줄 다음의 코드 블럭을 실행한다. 이 때 뒤에 나오는 elif 나 else 에 해당되는 코드 블럭은 실행하지 않고 건너 뛰게 된다. 만약 False가 있다면 바로 다음에 있는 elif 조건식을 검사하고 True 인 경우 elif 에 해당되는 코드 블럭이 실행된다. elif 는 if와 달리 첫번째 조건문만 아니면 여러개를 이어서 작성하는 것이 가능하다. 그리고 나무지 조건의 의미로 else 는 조건식이 없이 앞의 if 나 elif 조건들이 전부 False 일때 해당 코드 블록을 실행하게 된다.

여기서 elif는 else if 를 합쳐서 만들어진 키워드로 유닉스 쉘 스크립트 문법과 유사하다.

a = 1
if a > 0:
	print("a는 0보다 크다")
elif a < 0:
	print("a는 0보다 작다")
else:
	print("a는 0과 같다")

# a는 0보다 크다
# 나머지 print 함수는 실행되지 안고 건너 뛴다

참고 C의 if문

참고로 작성한 소스코드다 위와 동일하게 동작하는 if 문을 C로 표현한 코드 블록이다. C 에서는 코드 블록을 중괄호로 표시하니 표현의 다른점을 확인하자. 그리고 코드 블록을 명시 하지 않을 경우 한줄만 자동으로 코드 블록으로 인식하기도 한다.

int a = 1;
if (a > 0)
{
	printf("a는 0보다 크다\n");
}
else if (a < 0)
	printf("a는 0 보다 작다\n");
else { printf("a는 0과 같다\n"); }

성능과 가독성 좋은 조건문

조건문으로 보통 실행하는 코드 실행 분기를 나눈다는 것은 조건에 따라 실행하는 코드 즉, 논리적 자동화를 구현하는 부분이 있다. 때문에 복잡한 프로그램을 만들 수 록 조건문은 복잡해질 수 밖에없다.

성능을 조금이라도 높이기 위해서는 확률적으로 True 가 자주되는 조건식을 첫번째 if 에 넣는 것이 좋다. 이는 if의 조건식 검사후 elif 조건식을 검사하는 식으로 순차적으로 조건식을 검사히기 때문에 조건식 검사 횟수가 줄기 때문이다. 하지만 if와 else 밖에 없는 조건문은 차이가 없다.

가독성을 높이는 방법으로는 특정 조건을 기준으로 작성하는 것이 그나마 덜 복잡해 보인다. 특히 이중 조건문을 사용할 경우 차이가 크다. 그리고 해당 조건문에 대해서 주석을 달아주는 것도 좋다.

간단한 규칙이지만, 실무에서 잘 모르는 주니어 개발자들이 의외로 꽤 있었다.

반응형

'Python > 배경이 있는 파이썬' 카테고리의 다른 글

함수(function)  (0) 2024.05.24
반복문(while, for)  (0) 2024.05.11
불(bool)과 연산  (0) 2024.04.29
딕셔너리(dict)  (0) 2024.04.29
튜플(Tuple)  (1) 2024.04.27
반응형

개요

 파이썬의 Bool 타입(자료형)을 이해하기 위해서는 bool 타입의 탄생 배경을 아는 것이 중요하다. bool 타입은 현재 사용되고 있는 프로그래밍 언어 대부분이 갖고 있다. 정의는 True 와 False 두 가지 값밖만 가질 수 있다.

 bool 타입이 생기기 이전에는 int 라는 정수형 자료로 0일 경우 False 이외의 값을 갖는 경우 True와 같은 결과로 간주를 했었다. 하지만, 오랫동안 프로그래머들이 사용해본 결과 가독성이 나쁘다고 판단이 되어서 만들어지게 되었다. 예를 들어 C 에서는 함수가 제대로 동작하지 않았을 때, 음수 혹은 -1을 반환하는 등 오류 코드들은 음수를 일반적으로 사용했다. 그러나 조건문의 정의상 0 이외에는 True가 되기 때문에 분명 오류로 자주 사용하는 -1 은 True로 판단이 되는 등 논리적으로 혼란을 주기 때문에 조건문과 같은 대응 용으로 bool 을 사용하도록 한 것이다.

이 때문에 논리 연산과 비교 연산을 하게 될 경우 항상 그결과는 bool 타입으로 반환하게 된다. 이 때문에 bool 타입과 논리 연산자, 비교 연산자를 함께 공부하는 것이 좋다고 생각한다.

여담으로 필자 기억으로는 초기 C++에서 bool 타입이 추가 되었을때 이에 대해서 불만을 제기하는 몇몇 개발자의 푸념의 글도 본적이 있었다. 아직 성능이 중요한 시절이었기 때문에 자신은 익숙한데 굳이 bool 타입을 사용해야 하다보니 번거롭다는 내용이었다.

논리 연산자

논리 연산은 수학에서 정의된 논리 연산들이 있다. 오늘날 컴퓨터가 있게 되는 기본이 되는 연산이 된다. 오늘날 반도체로 컴퓨터를 만들 수 있게 된 이유가 바로 논리 연산이 가능하기 때문이다.

일반적으로 논리연산은 사칙연산보다 늦게 연산이 된다. 하지만 가독성을 위해서 복잡한 논리 연산을 하게 될 경우 괄호를 사용하여 명시하는 것을 권장한다.

and

연산 기호가 키워드 and로 좌우에 있는 값이 True 가 되어야 True를 반환한다.

True and True
# True

True and False
# False

False and True
# False

False and False
# False

or

연산기호가 키워드 or 로 좌우에 있는 값 중 하나라도 True 가 있으면 True를 반환한다.

True or True
# True

True or False
# True

False or True
# True

False or False
# False

not

연산기호가 키워드 not 으로 키워드 뒤에 있는 값을 반전을 한다. True 인 경우 False, False 인 경우 True를 반환한다.

not True
# False

not False
# True

비교 연산자

일반적으로 비교 연산자의 좌우에는 수치 연산이 가능한 숫자 형태의 값 혹은 숫자 값인 변수가 있어야 한다.

>

직관적으로 연산자의 왼쪽이 오른쪽 보다 클 경우 True를 반환한다.

2 > 1
# True

1 > 1
# False

1 > 2
# False

>=

연산자의 왼쪽이 오른쪽 값 보다 크거나 같은 경우 True를 반환한다. 그 외는 False 를 반환한다.

2 >= 1
# True

1 >= 1
# True

1 >= 2
# False

<

연산자의 왼쪽 값이 오른쪽 값보다 작을 경우 True를 반환한다. 그 외는 False 를 반환한다.

2 < 1
# True

1 < 1
# False

1 < 2
# True

<=

연산의 왼쪽 값이 오른쪽 값 보다 작거나 같을 경우 True를 반환한다. 그 외는 False 를 반환한다.

2 <= 1
# False

1 <= 1
# True

1 <= 2
# True

==

연산자의 왼쪽 값과 오른쪽 값이 같아야 할 경우 True를 반환한다. 해당 연산자는 독특하게 python 고유 기능으로 문자열(str)에도 사용이 가능하다.

2 == 1
# False

1 == 1
# True

1 == 2
# False

"abc" == "ab"
# False

"abc" == "abc"
# True

!=

연산자의 왼쪽 값과 오른쪽 값이 다를 경우에만 True를 반환한다. 같은 경우 False를 반환한다.

is

== 연산자와 비슷하지만 다르다. is는 좌우에 오는 것이 동일한지(메모리에 할당된 주소가 같은지) 확인을 한다. 때문에 연산은 이론적으로 == 연산보다 약간 빠르다. 값의 다향성이 적어 사실상 상수에 해당되는 True, False, None과 비교 할 때 많이 사용한다. 즉 이말은 == 연산에서 True 이나 is 연산에서는 False 경우가 존재하다는 의미이다.

is 연산자는 어느 정도 파이썬으로 개발 경험이 있는 초보 개발자도 잘 모르고 지나가는 경우가 많다.

a = "hello"
# b는 a와 같은 값이 연결되어 있음
b = a
a is b
# True

# 메모리 주소 확인 해볼 것
id(a)
id(b)

b = a[:4] + "o"
# b는 a와 같은 값이지만 서로 다른 곳에 할당되어 있음
a is b
# False

# 메모리 주소 확인해 볼 것
id(a)
id(b)

 

반응형

'Python > 배경이 있는 파이썬' 카테고리의 다른 글

반복문(while, for)  (0) 2024.05.11
코드 블록, 조건문(if)  (1) 2024.05.01
딕셔너리(dict)  (0) 2024.04.29
튜플(Tuple)  (1) 2024.04.27
리스트(list)  (0) 2024.04.27
반응형

개요

딕셔너리(Dictionary)는 줄여서 dict 으로도 표현된다. 키(Key)와 값(Value)로 저장된다. 값의 경우 변수처럼 어떤 자료형이라도 담을 수 있다. 단, 키를 기준으로 중복을 허용하지 않는다.

 이름에서 추측되는 것과 같이 영어사전이나 국어사전에서 어떤 단어의 뜻을 찾을 때 단어 혹은 키워드를 기준으로 먼저 찾고 거기에 해당되는 정보를 보는 것처럼 딕셔너리 자료형도 키워드를 키로 사용하여 해당되는 값을 찾을 수 있는 구조이다.

이런 딕셔너리 자료형은 많은 정보를 사전에 만든다음에 키워드로 찾는 것처럼 검색하는 것에 특화 되어 있다. 그리고 실제로 검색도 빠른 편이다.

 리스트 같은 순차적으로 저장되어 있는 경우 순서대로 정보를 확인하면서 검색을 해야하지만, 딕셔너리는 이미 검색할 키워드와 해당 값이 구분 되어 있기에 검색에서 유리하다. 대신 딕셔너리 자료형을 메모리에 생성할 때(저장 할 때)는 느린 편이다.

다른 언어인 C, C++ 같은 프로그래밍 언에어서는 파이썬의 딕셔너리 자료형과 유사한 것으로 해쉬 테이블(hash table), 해쉬 맵(hash map)이 있다.

정의

중괄호를 열고 닫음으로 정의 할 수 있다. 키 값은 항상 문자열(str)로 정의 되어야 한다.

a = { "name": "홍길동", 'dob': 1990 }
a
# { "name": "홍길동", "dob": 1990 }

b = {}
b
# {}

읽기

딕셔너리가 정의 되어 있는 변수에 대괄호를 붙여서 대괄호 안에 문자열로 키 값을 적으면 해당 값이 있는 경우 값을 불러오고 값이 없는 경우 에러가 발생한다.

c = {"name": "홍길동", "dob": 1990 }
c["name"]
# "홍길동"

c['name']
# "홍길동"

tmp = "name"
c[tmp]
# "홍길동"

c["address"]
# error:

수정 및 추가

읽는 경우와 비슷하나 조금 다르다. 대입 연산의 왼쪽에 딕셔너리 변수가 있으면 오른쪽의 값이 대입된다. 이 때 해당 키와 값이 없는 경우 새로 추가된다.

d = {"name": "마동석", "dob": 1988 }
d["name"] = "마동탁"
d
# {"name": "마동탁", "dob": 1988 }

d["address"] = "성남"
d
# {"address": "성남", "name": "마동탁", "dob": 1988 }

d[0]
# Error

요소 삭제

한쌍의 키와 값을 삭제할 수 있다. 삭제시 키를 중심으로 삭제된다.

 

d = {"name": "마동석", "dob": 1988, "address": "성남" }
del d["address"]
d
# {"name": "마동석", "dob": 1988 }

key in dict

딕셔너리 자료형에서 키가 포함되어 있는지 확인할 수 있다. 해당 키가 포함되어 있다면 True 포합되지 않았다면 False를 반환한다.

d = {"name": "마동석", "dob": 1988, "address": "성남" }
"name" in d
# True

"phone" in d
# False

주의할점

딕셔너리는 하위 단계(level)에 같은 이름의 키와 값을 정의 할 수 있다. 그러나 같은 단계(Level)에서 키가 중복으로 정의 할 수 없다. 만약 시도할 경우 덮어 써진다.

d = { "name" : "홍길동", "출신": {"출신": "서울"} }
# Error 아님

e = { "name" : "홍길동", "출신": "서울", "출신": "부산" }
# 마지막 꺼로 덮어 써짐

파이썬의 딕셔너리는 키가 문자열이면 대부분 사용이 가능하다. 심지어 공백문자(White space: 띄어쓰기나 줄바꿈)를 키로 사용이 가능하다. 그러나 가능하면 공백문자를 사용하지 않을 것을 권장한다. 이는 다른 프로그래밍 언어간 호환성을 위해서 이다.

a = {" ": "hello"}
a
# {" ": "hello"}

a[" "]
# "hello"
반응형

'Python > 배경이 있는 파이썬' 카테고리의 다른 글

코드 블록, 조건문(if)  (1) 2024.05.01
불(bool)과 연산  (0) 2024.04.29
튜플(Tuple)  (1) 2024.04.27
리스트(list)  (0) 2024.04.27
문자열(str)  (1) 2024.04.27
반응형

개요

튜플은 파이썬에서 사용하는 독특한 자료형 중 하나다. 리스트와 유사하지만 다르다. 그리고 튜플의 존재로 직관적인 코딩이 가능해지는 것도 있다.

튜플도 리스트처럼 복수의 자료형이나 값을 담기 위해 만들어 졌다. 그리고 튜플은 여러개의 값이 하나의 변수에 넣게 되는 경우 자동으로 만들어지는 자료형이다. 또는 해당 자료형을 활용해서 범용 함수나 클래스를 만드는 것이 가능해진다.

 리스트와 가장 큰 차이점은 튜플 자체 자료형 내부 값을 수정(삭제 포함) 할 수 없다. 이 의미는 튜플 자료형을 한번 쓰면 메모리에 영원히 남아 있다는 의미는 아니다.

정의

튜플의 자료형은 소괄호로 정의할 수 있다. 다만, 한개의 원소일 경우에만 특이하게 쉼표로 구분해줘야 한다.

a = ()
b = (1,)
c = (1, 2)
d = 1, 2
e = (1, '2', (3, '4'))

연산자

인덱싱[int]

리스트와 동일하게 원소들의 순서를 구분하며 대괄호로 그 순서를 지정하여 읽을 수 있다.

#    0  1  2  3
a = (1, 2, 3, 4)
a[1]
# 2

슬라이싱

역시 리스트와 동일하게 범위를 지정하여 반환한다. 슬라이싱이라는 단어 때문에 혼란이 있을 수 있는데, 원본 변수에 다시 대입하지 않은 이상 원본은 보존 된다.

#    0  1  2  3
a = (1, 2, 3, 4)
b = a[:2]
b
# (1, 2, 3)

len()

리스트와 동일하게 사용이 가능하다.

#    0  1  2  3
a = (1, 2, 3, 4)
len(a)
# 4

 

반응형

'Python > 배경이 있는 파이썬' 카테고리의 다른 글

불(bool)과 연산  (0) 2024.04.29
딕셔너리(dict)  (0) 2024.04.29
리스트(list)  (0) 2024.04.27
문자열(str)  (1) 2024.04.27
문자 code  (0) 2024.04.24
반응형

개요

리스트는 프로그래머들의 경험이 잘 녹아있는 자료형이다. 오래된 프로그래밍 언어인 C++ 에서는 vector<> 라는 자료형과 같으며, 그외에는 동일한 list 라는 자료형을 사용하고 있다.

리스트형은 내부에 같은 리스트를 포함한 자료형들 즉 데이터를 담을 수 있다. 이렇게 담는 의미가 강한 자료형을 container 자료형으로 불리기도 한다. 그리고 리스트내에 담긴 데이터를 원소라고 부른다.

또한 리스트는 순서가 있는 자료형이다. 이러한 순서(혹은 순번)을 index라고 표현하며, 첫 원소의 index는 0이다.

list 의 index가 0부터 시작하는 이유

현재 대부분의 프로그래밍 언어의 문법들은 C 에서 많은 영향을 받았다. 이 때 C 에서는 list와 같은 연속적인 데이터를 저장하기 위해서 array 자료형을 제공하였다. 이 array는 연속적인 데이터가 시작되는 메모리의 위치를 의미했다.

그리고 array의 작동원리는 메모리의 특정 시작지점으로 부터 얼만큼(방향은 부호) 떨어진 곳을 읽느냐는 의미로 설계 되어있다보니 자연스럽게 메모리에서 시작지점에 저장된 데이터를 읽으려면 0 부터 시작하게 되었다.

그리고 기존의 많은 프로그래머들은 이 방식이 익숙해졌다. 결국 대부분의 연속형 자료형의 인덱스는 0 부터 시작하도록 만들어지고 사용되고 있다.

정의

리스트는 대괄호로 정의할 수 있다. 리스트에 원소(혹은 요소)로 담기는 자료형은 제약이 없다. 심지어 리스트도 담길 수 있다.(그러나 좋은 코드는 규칙성이 있게 담거나 특정 자료형을 모아서 담는 것이 좋다.)

a = []
a
# []

b = [1, 2, 3]
b
# [1, 2, 3]

c = ["1", "hello", 'world']
c
# ["1", "hello", "world"]

d = [1, 'hello', b]
d
# [1, "hello", [1, 2, 3]]

연산

리스트간 연산이 가능하다. 다만 자세히 관찰하면 문자열의 연산과 유사점이 있다.

list + list

두 개의 리스트 덧셈을 할 경우 연산자의 좌측 리스트에 이어서 연사자의 우측 리스트가 연결이 된 리스트를 반환한다. 문자열의 덧셈 연산과 유사하다. 다만, 문자열의 덧셈과 차이점은 문자열의 경우 동일한 문자열 자료형만 덧셈이 가능하다. 반면 리스트는 어떤 원소가 있어도 상관이 없다.

a = [1, 2]
b = [3, 4]
c = a + b
c
# [1, 2, 3, 4]

list += list

할당 연산자와 동일하게 동작한다. 연산자 좌측 리스트와 우측 리스트의 덧셈 연산을 한 결과를 좌측 리스트 변수에 대입하게 된다.

a = [1, 2]
b = [3, 4]
a += b
a
[1, 2, 3, 4]

list * int

앞의 list를 뒤에 있는 정수 만큼 더한 것과 같다. 문자열의 곱연산과 같다.

a = [1, 2]
b = a * 3
b
# [1, 2, 1, 2, 1, 2]

인덱싱[int]

리스트는 순서 즉 index가 있기때문에 처음 원소를 0번으로 정의하고 이후부터는 순서대로 번호를 붙일 수 있다. 이러한 번호로 읽거나 수정이 가능하다. 이런 대괄호 기호를 인덱싱 연산자라 부른다.

주의할 점은 인덱싱 연산자 내에 들어가는 숫자는 반드시 정수가 되야 한다. 그리고 인덱싱 연산자내에 범위를 벗어나는 index가 들어간 경우 에러가 발생한다.

# IDLE Shell
#    0  1  2  3
a = [1, 3, 5, 7]
a[0]
# 1

a[2]
# 5

a[2] = 0
a[2]
# 0

a[4] = 1
# Error: indexError

a[1.1]
# Error

파이썬의 독특한 점은 인덱싱에 음수를 사용할 수 있다. 인덱스에 -1 이 들어갈 경우 리스트의 가장 마지막 원소를 반환한다. 그리고 음수에서 작아질 수록(숫자가 커질 수록) 역순으로 반환하게 된다.

# IDLE Shell
#     0        1        2
a = ["hello", "world", "??"]
a[-1]
# "??"

a[-2]
# "world"

리스트 속에 있는 리스트에 접근할 경우 가장 좌측 인덱스가 가장 바깥부터 접근을 한다.

# IDLE Shell
#     0        1        2
a = ["hello", "world", "??"]
a[-1]
# "??"

a[-2]
# "world"

위의 예시의 경우 리스트 문법의 동작 원리를 설명하기 위한 것으로 실무에서는 이러한 복합적인 구조를 거의 사용하지 않는다. 완전한 2차원 리스트 혹은 완전한 3차원 형태로 사용하는 경우는 있다. 이는 프로그래밍을 할때 최대한 단순한 구조로 하는 것이 유지 보수에 유리하기 때문이다.

슬라이싱

리스트의 특정 구간을 자를 수 있다. 범위를 지정할 때는 기호 콜론(:)을 사용한다. 만약 처음이나 끝을 의미할 경우 해당 인덱스 값을 굳이 안넣어도 된다. 직관적으로 1:3은 마치 1~3 과 같은 의미가 된다.

# IDLE Shell
#    0  1  2  3  4
a = [1, 3, 5, 7, 9]

b = a[1:3]
b
# [3, 4, 7]

c = a[:3]
c
# [1, 3, 5, 7]

d = a[2:]
d
# [5, 7, 9]

대입

리스트의 대입 연산은 일반적인 숫자 대입과 다르다. 일반적인 숫자를 대입할 경우에는 값이 복사되어 변수에 담긴다. 이렇나 자료들은 immutable이라 한다. 하지만 리스트와 같은 자료형은 mutable로 구분되어 대입연산으로 다른 변수에 대입을 해도 값을 복제하지 않고 값을 공유한다.

만약 C를 공부한적이 있다면, mutable은 얕은 복사, immutable은 깊은 복사와 거의 같은 개념이다. immutable과 mutable 자료형에 대해서는 클래스 이후에 다시 살펴 보도록 하자.

# immutable
va = 1
vb = va
va = 3
va
# 3
vb
# 1

# mutable
la = [1, 2, 3]
lb = la
la[1] = 4
lb
# [1, 4, 3]

# 아래의 경우 la에 새로운 리스트가 할당되고
# lb는 기존의 리스트가 유지 된다
la = [4, 5, 6]
lb
# [1, 4, 3]

언박싱(unboxing)

파이썬의 독특한 문법으로 복수의 변수에 리스트를 대입 연산을 시도할 경우 변수명의 개수와 리스트의 원소 개수가 같은 경우 각각의 원소가 순서대로 변수에 들어가게 된다. 이때 리스트 자료형이 풀어지는 것과 같다(그래서 언박싱이라 이름을 지은 듯하다).

a = [1, 2, 3]
b, c, d = a
b
# 1

c
# 2

d
# 3

element in list

리스트 내에 동일한 원소가 있을 경우 True, 없을 경우 False를 반환한다.

a = [1, 2, 3, 4]
1 in a
# True

0 in a
# False

함수

len()

리스트의 길이를 반환해준다. 리스트의 길이는 리스트에 들어 잇는 원소의 개수이다. 리스트와 유사한 문자열에서도 사용된다.

a = [1, 2, 3, 4]
len(a)
# 4

len([1, 2, 3, 4, 5])
# 5

del

리스트에 있는 원소를 삭제해준다. 인덱싱과 슬라이싱을 응용하여 사용이 가능하다. 주의해야 할 점은 index로 삭제할 경우 기존 index가 삭제되면서 index가 바뀌게 되는 점이다. index가 바뀌면서 발생하는 문제를 피하기위해서 역순으로 삭제하는 요령이 있다.

#    0  1  2  3  4
a = [1, 2, 3, 4, 5]
del a[1]
a
# [1, 3, 4, 5]

del a[2:]
a
# [1, 3]

 

반응형

'Python > 배경이 있는 파이썬' 카테고리의 다른 글

딕셔너리(dict)  (0) 2024.04.29
튜플(Tuple)  (1) 2024.04.27
문자열(str)  (1) 2024.04.27
문자 code  (0) 2024.04.24
숫자형(int, float)  (0) 2024.04.24
반응형

개요

 문자열은 최소한 문자 한개 이상이 보여 있는 것을 의미한다. 물론 프로그래밍 언어에서는 열(array)형태의 자료형 안에 한 글자라도 들어 있어도 문자열로 취급한다. 문장의 개념과 혼동이 가능하겠으나 문장의 단위는 인간의 언어에서 구분하는 기준이고, 문자열은 여러 문장도 담을 수 있기 때문에 좀 더 다른 개념으로 이해하는 것이 좋다.

 컴퓨터를 사용한 이후 오랜 시간 동안 프로그래머들은 경험상 문자 기준으로 글자를 다루는 것 보다 문자열 단위로 다루는 것이 편리 하다는 것을 알게 되었다. 이러한 흔적으로 C 같은 오래된 언어에는 문자열을 다루는 기본 자료형이 없다. 문자열은 기본적으로 순서가 있는 문자들을 다루기 때문에 파이썬의 리스트 자료형과 비슷한 특징을 가지고 있다.

(해당 예제들은 IDLE Shell 혹은 python shell 에서 실행하는 것이 편하다)

문자열 정의

 문자열을 정의 하는 방법은 쌍따옴표로 시작해서 쌍따옴표로 끝나거나 따옴표로 시작해서 따옴표로 끝나면 된다. 쌍따옴표로 시작한 문자열 내에서의 따옴표는 단순한 문자 기호로 인식이 되며, 반대로 따옴표로 시작한 문자열 내에서 쌍따옴표는 문자 기호로 인식된다.

 만약 쌍따옴표 내에서 쌍따옴표를 문자 기호로 인식을 시키기 위해서는 앞에 역 슬래스(혹은 한국원화 기호)를 해주면 된다. 이는 쌍따옴표로 시작한 문자열 중간에 쌍따옴표를 그냥 넣게 되면, 앞에서 정의한 문자열 문법에 의해서 해당 위치까지 문자열이 끝나는 것으로 인식 되기 때문이다.

"min: hello"
'han: hello'
# 둘다 동일한 문자열

"min: 'hello'"
# 따옴표는 문자 기호로 인식됨

'han: "hello"'
# 쌍따옴표는 문자 기호로 인식됨

"min: \"hello\""
# 문자열 내에서 \기호 뒤에 있는 따옴표는 문자 기호로 인식됨

역슬래시 특수문자

 문자열 내에서 특정한 기호를 사용하기 위해서는 역슬러시를 사용하여 표현할 수 있다. 앞의 쌍따옴표나 따옴표의 경우 상황에 따라서 특수문자로 사용된 경우이다.

 즉, 줄바꿈, 탭, 앞줄 부터 시작을 표시하는 특수기호가 존재한다. 이러한 특수 문자를 표현할 경우 '\'(역슬러시)를 사용하여 표현한다. 이러한 표기법은 오래전부터 사용되었기 때문에 다른 프로그래밍 언어에서도 비슷하게 사용된다.

string 표기 이름 의미
\n 개행문자(Line Feed) 한줄 아래로 이동
\t 탭(tab) 탭키를 누른 것 만큼 이동
(일반적인 탭은 7, 8칸을 뛴 것과 같다)
\r 개행문자
(Carriage Return)
커서(글자를 쓰는 칸)를 현재 줄 앞으로 이동(윈도우즈 내부에서 사용함)
\' 작은 따옴표 작은 따옴표 표기
\" 큰 따옴표 혹은 쌍따옴표 큰 따옴표 표기
\\ 역 슬러시 역슬러시 표기

 여담으로 윈도우즈에서는 파일 경로를 표기하기 위한 구분자로 역슬러시를 사용하다 보니 해당 경로를 문자열로 받게 될 경우 역 슬래시가 2번 표기되는 것을 볼 수 있다. 하지만, 실제로 print() 로 화면에 출력하거나 파일로 저장할 경우에는 하나만 보이게 된다.

Formatter

 초기 프로그램들이 사람과 소통하는 가장 간단한 방법은 문자열을 화면에 보여주는 것이다. 특히 세금 계산서나 은행에서 사용하는 공문서들은 형식(Format)이 정해진 경우가 많다. 이처럼 형태가 정해진 문자열을 다룰 경우 많이 사용되는 방식이다.

 기본적으로 포맷 형식에는 샘플이 되는 문장이 있고 이를 어떻게 처리하느냐는 이후 문법 방식에 따라서 다르다.

%

 파이썬에서 가장 초기에 사용되던 방식이다. C 의 printf() 함수의 방식과 비슷하여 printf 방식 포멧팅이라고도 한다. python 2 에서 주로 사용된 방식으로 오래된 소스코드를 보면 쉽게 볼 수 있다. 샘플이 되는 문장에 변형이 가능한 자리에는 %d, %f, %s 와 같은 미리 정의 되어 있는 특수문자를 넣고 해당되는 값에 순서대로 넣는 것이 가능하다.

a = "%s님의 잔액은 %d원 입니다.\n이자율 %f\%" % ("오리", 101, 3.3)
print(a)
# 오리님의 잔액은 101원 입니다
# 이자율 3.300000100%

실수인 숫자의 경우 자리수를 제한 해야하는 경우에는 자리수에 해당하는 값도 추가 해줘야 한다.

a = "%s님의 잔액은 %d원 입니다.\n이자율 %.2f\%" % ("오리", 101, 3.3)
print(a)
# 오리님의 잔액은 101원 입니다
# 이자율 3.30%

format()

 권장하는 방식 중 하나이다. str 형에는 내부에 format() 함수가 들어 있어 해당 함수를 호출하여 문자열 내에 들어간 변수를 넣어주면 된다. 순서를 명시해 줄 수 도 있고 안해 줄 수도 있다.

 가장 많은 고민이 들어간 문법이기 때문에 공식 문서에서 내용이 방대한 편이다.

a = "{}님의 잔액은 {}원 입니다.\n이자율 {}%".format("오리", 101, 3.3)
print(a)
# 오리님의 잔액은 101원 입니다
# 이자율 3.30000001%
b = "{1}님의 잔액은 {0}원 입니다.\n이자율 {2}%"
b = b.format(101, "오리", 3.3)
print(b)
# 오리님의 잔액은 101원 입니다
# 이자율 3.3%

f-string

 python 3.6 부터 지원한 방식이다. 직관적인 편이기 때문에 권장하고 있다. 문자열의 시작전 f로 시작하여 중괄호 안에 변수가 되는 값 혹은 수식을 직접 삽입할 수 있다.

a1 = "오리"
a2 = 101
a3 = 3.3
a = f"{a1}님의 잔액은 {a2}원 입니다.\n이자율 {a3}%"
print(a)
# 오리님의 잔액은 101원 입니다
# 이자율 3.30000001%

 포멧이 되는 표현식(expression)의 경우 키워드가 아닌 중괄호를 표현하고 싶은 경우 중복해서 사용하면 기호로 인식된다.

이렇게 포멧 문자를 간단히 확인했는데, 자신이 초급 이상으로 좀 더 자세한 것을 알기 위해서는 공식문서를 확인해보면 된다.

문자열과 연산

문자열을 편의상 string 혹은 str로 표현을 한다.

str + str

 문자열과 문자열을 더 할 수 있다. 이 경우 두 문자열이 합쳐진 하나의 문자열이 된다.

a = "ba"
b = "poo"

c = a + b
# c == "bapoo"

str += str

 연산자의 좌측 문자열과 우측 문자열을 합친다음에 왼쪽 변수에 대입을 한다.

a = "hello"
b = "world"
a += b
a
# "helloworld"

str * int

문자열에 숫자를 곱한 경우 해당 문자열을 반복해서 더한다.

a = "-" * 8
a
# "--------"

str *= int

연산자의 좌측 문자에 우측 숫자만큼 반복한 문자열로 대입한다.

a = "-"
a *= 8
a
# --------

 

문자열 함수

문자열에 사용이 가능한 내장형 함수이다. 함수에 대한 설명은 이후 함수 항목에서 설명한다.

str()

숫자 타임의 int, float ㅎ여태로 자료형을 문자열로 변환 해준다.

a = 10
b = str(a)
b
# "10"

len()

문자열이 들어 잇는 문자열의 길이를 반환한다. 공백이나 줄 바꿈 문자도 하나의 문자로 인식한다. 문자열 뿐만 아니라 길이가 있는 list 형에서도 사용이 가능하다. 다만, list 자료형에 대해서는 나중에 다룬다.

a = "hello"
len(a)
# 5

b = "안녕"
len(b)
# 2

주의할 점

문자의 경우 이전에 공부한 문자 code 에 의해서 문자 종류에 따라서 한 문자를 저장하는 바이트 크기가 다르다. 즉, 문자열이 차지는 하는 메모리 용량과 문자의 길이는 다른 개념임을 인지해야 한다. 그리고 임베디드 같은 저수준 프로그래밍 하는 환경에서는 적은 메모리를 사용해야 하는 경우가 있기 때문에 이에 대해서도 주의 해야 한다. Python 에서 문자열이 차지하는 바이트 크기를 알기 위해서는 문자열을 bytes로 형변환을 하여 len() 함수를 사용하면 된다.

 

반응형

'Python > 배경이 있는 파이썬' 카테고리의 다른 글

튜플(Tuple)  (1) 2024.04.27
리스트(list)  (0) 2024.04.27
문자 code  (0) 2024.04.24
숫자형(int, float)  (0) 2024.04.24
변수(variable)와 상수(constant)  (0) 2024.04.23
반응형

과거 처음으로 딥러닝 관련 프로젝트가 상표와 디자인에서 유사 이미지 검색 시스템을 만드는 것이었다.

2019년 특허청에서 발주한 프로젝트였고, 당시 새로 시도하는 것이었기에 서로 안하려고 했던 프로젝트였다. 나는 TensorFlow와 keras를  처음으로 공부했는데, CNN 에 대해서는 과거 대학원 시절에 익숙한 연산들이었기에 이해하는데 어려움은 없었다.

당시 딥러닝 쪽 포럼등은 주로 딥러닝 망의 내부에서 무슨일이 벌어지고 있는지를 관찰을 한참 하던 시기였다. 즉, 당시 레이어에서 무슨일이 벌어지는지 이해하는 사람이 적었던 시절이다. 다만, 영상처리 공부를 해본 사람 입장에서는 CNN이 여러 콘볼루션 연산을 통해서 사실상 미분 등 픽셀에 대해 다양한 연산이 벌어지고 있고, 다양한 detector 알고리즘을 경험해봤다면, 내부에서는 필셀간 연산을 통해서 검출하려 한다는 것도 어느 정도 이해가 될 것이다.

이때 컴퓨터 비전을 처음 접한 사람들은 CNN이 블랙박스로 생각을 하겠지만, 사실 전통적으로 사람이 직접 설계하던 검출기를 딥러닝 방식으로 통해 자동으로 형성하게 설계하도록 구조를 변경한 것 뿐이다. 그러니 다층 더 깊은 층을 만들 수 록 더 다양한 연산을 해볼 수 있으니 품질이 높게 나오는 것은 당연한 것이다. 사람으로 치면 생각을 더 많이 해본다는 뜻이 되니까 말이다.

아무튼 vector DB가 등장한 사실은 2024년 초에 알게 되었다. 아마 2023년에 등장한 것으로 보이지만, 구성이라던거 설명한 것을 보면 2019년에 내가 직접 구현한 유사 이미지 검색 시스템과 거의 같다. 다만 설명부분에서 문제가 있는지 COS distance 에 대해서 각도로 이해하는 분들이 유튜브에 종종 보이더라. 임베디드 레이어에서 COS Distance의 의미는 다차원 벡터에서 동일 성분간 얼마나 유사한지를 판단하는 연산이 된다. 3차원으로 차원을 낮춰서 생각하면 이해가 쉬울 것이다.

근데, 이게 무리도 아닌게 당시 박사님들과 싸우면서 해당 시스템을 완성했는데, 설명을 해도 이해를 못 하셨었었다. 그래서 이 프로젝트가 여러모로 어려웠기 때문에 기억에 남는다. 그리고 이 프로젝트 이후 같이 참여 했던 교수님의 경우 이 때 기억에서 인상이 깊었는지 AI 회사에 실장으로 오라는 제의를 해주시기도 했는데, 지금은 그 때 갈껄 하고 후회하는 중이다.

해당 시스템은 국내에 특허로 내었는데, 당시 PM 맡으신 대표님이 내 이름은 빼놓아서 2개월전에 요청을 해서 추가하기로 합의를 보았다. 다시 이러한 딥러닝 분야를 연구하고 싶은데, 정작 비슷한 연구하는 곳에서는 해당분야 3년이 안되서 인지 면접도 못 가고 서류 탈락이 되고 있다. 그 동안 너무 다양한 분야를 한 것이 문제가 된 것 같다.

반응형

+ Recent posts