반응형

개요

반복문은 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 > 배경이 있는 파이썬' 카테고리의 다른 글

코드 블록, 조건문(if)  (1) 2024.05.01
불(bool)과 연산  (0) 2024.04.29
딕셔너리(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
반응형

개요

 자료형은 프로그램에서 값을 다루기 위해서 정의된 것이다. int와 float는 기본적으로 정의 되어 있는 기본 자료형이다. 내부에서는 숫자도 구분하고 문자열도 구분 한다. Python 에서는 대입하는 결과를 문법이 유추해서 변수의 자료형을 정의하여 값을 대입한다.

 이 때문에 코드를 작성했을 때 숫자 자료형을 명확히 구분하지 않는 것 같으나 내부적으로는 구분을 하고 있다. 정수형은 int, 실수형은 float로 구분하고 있다. 실수형이 표현 가능한 숫자의 범위가 더 크기 때문에 소수점이 포함된 수치와 정수형 수치를 연산하게 되면 python은 자동으로 실수형으로 자료형을 바꿔서 연산을 한다.

 int 형은 정수형만 표현하여 내부적으로 0과 1을 하나씩 카운트 하는 방식이라 비교적 정확한 연산이 가능하다. 반면 float  는 소수를 포함한 실수형이라 내부적으로 실수부 자리 표기를 분리해서 사용하기 땜누에 비교적 큰 범위의 숫자 표현이 가능하지만 연산 횟수가 많으면 오차가 발생한다. 이 이유는 진법에 의한 수학적인 이유 때문이다. float 형은 잦은 연산을 하지 않는 것이 좋고 유효숫자를 정해 놓는 것이 오차를 줄일 수 있다.

 float 형에서 많은 연산을 하면 왜 오차가 발생하는지는 기회가 되면 정리하도록 하자.

산수 연산자(Arithmetic Operators)

숫자형은 기본적인 사칙연산을 사용할 수 있다. 이외 기본적인 연산자에 대해서 살펴보자. 만약 C 나 다른 언어를 알고 있다면 Python 만의 독특한 연산자도 보일 것이다. 반대로 python 에서는 없어진 연산자도 있을 것이다.

+

더하기 연산자이다. 이 연산자를 기준으로 좌우의 값을 더한다. int 형 값과 float 형의 값을 연산하게 될 경우 최종적으로 float 값으로 반환이 된다.

1 + 1.1
# 2.1 (float)

1.1 + 1
# 2.1 (float)

1 + 1
# 2 (int)

*

 곱 연산자이다. 연산자의 좌우의 값을 곱한다. 왼쪽이나 오른쪽 값 중에 float 형이 있는 경우 결과는 float 형이 된다.

1 * 1
# 1

2 * 2
# 4

2 * 1.1
# 2.2

-

빼기 연산자이다. 연산자의 오른쪽에 있는 값을 왼쪽에 있는 값에서 뺀다. 마찬가지로 int와 float 값을 연산할 경우 최종 결과는 float 형이 된다.

3 - 1
# 2

1 - 3
# -2

1.1 - 2
# -0.9

/

나누기 연산자읻다. 일반적으로 타 프로그래밍 언어에서는 연산자의 좌우가 int 형일 경우 몫만 반환한다. 그러나 파이썬에서는 몫으로 딱 나눠떨어지지 않으면 float 형으로 변화해서 소수점으로 결과를 반환한다.

3 / 2
# 1.5

10 / 2
# 5

//

몫 연산, 일반적인 타 프로그래밍 언어에서 나누기 연산자를 사용한 결과와 같다. 나누었을 때 나머지가 있어도 무시하고 몫만 반환한다.

3 // 2
# 1

10 // 2
# 5

%

나머지 연산. 연산자의 오른쪽 값으로 나누었을 때 나머지만 반환한다. 이때 나머지는 int 형으로 반환한다. 프로그래밍에서 은근히 많이 쓰이는 연산이다.

3 % 2
# 1

10 % 2
# 0

**

제곱 연산자이다. 파이썬의 독특한 문법이다. 실제로는 여러번 곱하는 걸 코드상 간당하게 작성한 것이기 때문에 여러번 곱연산 한것과 성능차이는 크지 않다.

2 ** 3
# 8

할당 연산자(Assignment Operators)

축약된 형태의 연산자로 연산자의 왼쪽 값과 오른쪽 값을 연산한 결과를 다시 왼쪽 변수에 대입하라는 의미이다. 대입 연산자처럼 왼쪽은 변수가 되어야 한다.

+=

 왼쪽의 값에 오른쪽에 있는 값을 더한 뒤에 다시 왼쪽 변수에 대입을 한다. 만약 왼쪽이 int 형이고 오른쪽이 float 형인 경우 왼쪽도 float 형이 된다.

a = 1
a += 1
a
# a 는 2

a += 1.1
a
# a 는 3.1

*=

 연산자의 왼쪽 변수값에 오른쪽 값을 곱 연산한 결과를 왼쪽 변수에 대입을 한다.

a = 1
a *= 3
a
# a 는 3

a *= 3
a
# a 는 9

-=

연산자의 왼쪽 변수 값에 오른쪽 값을 빼기 연산한 결과를 왼쪽 변수에 대입을 한다.

a = 10
a -= 2
a
# 8

/=

연산자의 왼쪽 변수 값에서 오른쪽 값을 나누기 연산한 결과를 왼쪽 변수에 대입을 한다.

a = 10
a /= 2
a
# 5

a /= 2
a
# 2.5

//=

 연산자 왼쪽 변수 값에 오른쪽 값으로 나누기 연산한 몫을 왼쪽의 변수에 대입한다.

a = 5
a //= 2
a
# 2

%=

연산자의 왼쪽 변수 값에 오른쪽 값으로 나눈 나머지를 왼쪽 변수에 대입한다.

a = 5
a %= 2
a
# 1

**=

연산자의 왼쪽 변수값에 대한 오른쪽 값 만큼 제곱하여 왼쪽 변수에 대입한다.

a = 2
a **= 3
a
# 8

a **= 2
a
# 64

 

반응형

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

문자열(str)  (1) 2024.04.27
문자 code  (0) 2024.04.24
변수(variable)와 상수(constant)  (0) 2024.04.23
개발 환경 만들기  (0) 2024.04.22
파이썬 3 설치  (0) 2024.04.22
반응형

개요

프로그램에서 가장 기본적이면서 중요한 개념이다.

흔히 프로그램에서 주 메모리를 사용한다는 것은 변수에 값이 담기거나 변수가 있을 때와 동일하다.

변수 정의

 파이썬에서는 미리 동작이 지정되어 있는 키워드인 예약어를 제외하고 문자로 시작하는 대부분의 단어를 변수명으로 사용할 수 있다. 그리고 변수명은 가장 맨앞의 문자가 숫자가 와서는 안된다. 대입 연산자를 기준으로 앞(좌항)의 문자들이 변수명으로 인식된다. 여기서 대입 연산자는 일반 수학에서 등호(=)를 대입 연산자라 한다.

 대부분의 다른 프로그래밍 언어들은 변수를 지정할 때 변수의 형(type) 또는 변수임을 알리는 키워드를 사용한다. 파이썬의 경우 변수를 정의 할 때 별도의 타입 키워드를 사용하지 않는다.

 파이썬(3부터)에서는 기본 스크립트 문자 인코딩을 UTF-8 코드를 지원하기 때문에 변수명에 영문 + 숫자 외의 다른 언어를 사용할 수 있다. 문자 인코딩에 대해서는 향후에 설명을 한다.

상수의 정의

상수는 코드상 직접 숫자나 문자열(문장)을 작성한 것을 상수로 취급한다.

수학시간의 방정식에서 항상 정해진 값을 상수라고 한다. 파이썬에서의 상수는 숫자나 문자열을 적은 것 자체를 상수로 취급한다. 이는 문자도 내부적으로는 숫자 코드로 작성되었기 때문이다.

True, False, None 과 같은 예약 키워드도 상수로 취급한다.

상수는 대입연사자의 좌항, 즉 왼쪽에 있을 수 없다. 이는 상수의 정의상 변하면 안되기 때문이다.

# 상수
1
3
44
"hello"
False
True
None

대입 연산자(=)

대입 연산자는 오른쪽에 있는 값을 왼쪽에 넣는 것을 의미한다.

앞에서도 잠시 언급했지만, 해당 연산자의 왼쪽에는 상수가 올 수 없다. 예를 들어 (1 = 2)라고 하면 1은 이제부터 2이다 라는 말인다. 논리적으로도 말이 안된다.

다른 연산자들보다 우선순위가 가장 낮아 가장 나중에 연산된다.

a = 1
# a는 1의 값을 갖게 됨

1 = 2
# 문법 에러

뭘보누 = 3
# 뭘보누 라는 변수는 3이라는 값을 갖게 됨

print(뭘보누)
# 3
반응형

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

문자 code  (0) 2024.04.24
숫자형(int, float)  (0) 2024.04.24
개발 환경 만들기  (0) 2024.04.22
파이썬 3 설치  (0) 2024.04.22
배경이 있는 파이썬  (0) 2024.02.22
반응형

개요

Windows 를 제외하면 대부분의 OS(주로 유닉스 계열로 리눅스로 불리는 것들과 OS X라 불리는 apple 에서 만든 OS들)는 기본적으로 Python3가 설치되어 있다. 이 때문에 입문시 초기 파이썬 설치는 Windows 에서만 진행하면 된다.

다운로드

 구글에서 python 으로 검색하거나 주소창에 python.org 를 직접 입력하여 접속을 해도 된다. 다운로드 받을 수 있는 버전은 시기에 따라서 차이가 있다. 현직 개발자가 아니거나 입문자라면 최신버전을 받아도 무난하다.

 python 3.10 부터 많은 부분이 변화 되었기 때문에 하위 호환이 안되는 경우가 있다. 대신에 이러한 변호로 인해 python이라는 언어가 더 급진적으로 발전하게 된다. C#의 경우 2년만에 2.0 에서 6.0 까지 버전업을 한 사례도 있다.

 

설치

다운로드 받은 파일을 실행하면 python을 설치할 수 있다. 처음 python을 설치한다면 이 때 하단의 Add python.exe to PATH 항목을 체크하고 나서 install Now 부분을 클릭하여 설치를 진행하면 된다.

Add python.exe to PATH의 의미

원도우즈 뿐만 아니라 대부분의 운영체제에서는 '환경변수'라는 것이 존재한다. 이 환경변수내에 파일 경로 혹은 폴더 경로가 설정되어 있다면, 해당 파일 경로가 아닌 곳에서도 프로그램을 실행할 수 있다.

즉, 우리가 앞으로 만드는 python 소스코드를 python.exe (혹은 python.out)을 통해서 실행되기 위해서는 환경변수에 추가 되어야 아래와 같이 간단하게 실행할 수 있다.

# ${} 은 보통 글자 내용에 해당하는 특정한 값을 의미함
python.exe ${python source code file path}

만약 환경변수에 등록을 하지 않았다면 다음과 같이 실행을 해야한다.

c:\users\${user}\AppData\Local\Programs\Python\Python311\python.exe ${python source code file path}

설치 확인

버전 확인

명령 프롬프트 혹은 Power shell 에서 다음 명령어를 실행하면 된다. 실행 결과로 버전 정보가 나오면 정상적으로 설치가 된 것이다. 정상적으로 확인 되었다면 실습 준비가ㄷ된 것이다.

 

python --version

명령 프롬프트 열기

윈도우 키를 누르고 cmd를 입력하면 '명령 프롬프트'가 보인다. 이를 클릭하여 실행하면 된다.

power shell 열기

윈도우 키를 누르고 power shell을 입력하면 power shell 이 보인다. 이를 클릭하여 실행하면 된다.

반응형

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

문자 code  (0) 2024.04.24
숫자형(int, float)  (0) 2024.04.24
변수(variable)와 상수(constant)  (0) 2024.04.23
개발 환경 만들기  (0) 2024.04.22
배경이 있는 파이썬  (0) 2024.02.22
반응형

Computer Vision 이미지 자료형

배경

Python2 시절까지만 해도 성능을 중요시했던 컴퓨터 비젼 분야는 오랫동안 C/C++ 계열이 메인이었는데, 지금은 컴퓨터 비젼을 한다면 Python도 필수로 해야 하는 시대가 되었다. 이건 딥러닝 파급의 효과가 가장 컸다. 다만, 최근에 내가 놓친 부분을 알기위해서 빠른 지식 습득 수단으로 강의를 듣고 있는데, 강의에서도 그렇고 회사에서 기술이전으로 로봇공학쪽 박사 포닥중인 강의 하시는 분도 그렇고 그냥 다르니 주의해라는 듯이 설명해서 내 입장에서는 난감했다. 사실 본래 자료형이 만들어진 목적이 있기 때문이다.

그래서 끄적여 본다.

Python 이미지 처리 모듈

기본적으로 이미지의 첫 출발은 이미지를 메모리에 올리는 것 부터 시작이 된다. Python 에서는 대표적인 모듈이 3가지가 존재한다. PIL, Scikit Image, OpenCV. 이중에서 현재는 OpenCV를 많이 사용하고 있다.다만, 대부분 이 라이브러리들은 이미지 파일을 로드하게 되면 numpy 모듈의 array로 로드를 하는 특징이 있다.

PIL

Python Image Library 로 초기 Python 영상처리 많이 사용했다. 필자도 OpenCV 보다 PIL 을 주로 썼었는데, 이는 OpenCV의 경우 BGR로 로드하는 반면 이 라이브러리는 RGB로 로드가 되었기 때문에 이런 변환 코드를 덜짜기 위해서 썼었다. 파이썬은 성능보다 생산성을 추구하였으니 말이다. 문제는 PIL 이 현재는 유지보수가 잘 안되고 있다. 지금의 PIL는 fork 된 프로젝트 중에서 호환만 경우 유지되고 있는 수준이다.

Scikit Image

Scipy 기반으로 제공되는 라이브러리이다. Scipy는 SCI 이름에서 알 수 있듯이 연구 용도로 많이 사용한다. 경우에 따라 Scipy 는 상당히 높은 수준의 연산을 도와주는 모듈들이 있다. 그러나 필자를 포함해서 널리 사용되지는 않는 것 같다.

OpenCV

인텔에서 개발하다가 오픈 소스로 전환된 라이브러리다. 이미지 로드시 BGR로 메모리에 올라가는 것을 특징으로 갖는데 이는 초기에 성능을 위해서 인텔 CPU가 리틀엔디안 방식으로 데이터를 처리하기 때문에 일부러 뒤집은 탓이다. OpenCV1 시절은 C, OpenCV2 시절은 C/C++, OpenCV3 에서는 Java/Python 이런식으로 확장되어 왔다. Mat 이라는 자체 이미지 자료구조를 가지고 있었는데, Python 에서는 numpy.array 자료구조를 사용한다.

개인적으로 numpy.array로 로드 되는 것을 처음 알았을 때는 기존 Mat 보다 이미지 정보가 적어서 불편하다 생각했지만, 수학적인 연산도 자연스럽게 사용할 수 있었고 그렇지 않아도 느린 버전업이 빨라 졌다. 즉 버그 픽스가 빨라졌다는 것이다. numpy 경우 Matlab 처럼 멀티 스레드로 메트릭스 연산을 하기 때문에 C로 단일 스레드로 연산한것 보다 빠르다.

numpy.array

numpy 모듈은 태생이 수학자들이 만든 C로 만들어진 모듈들이다. Python 이 런타임이 느린 언어이지만, 이 모듈로 간단히 몇 줄로 크게 뒤지지 않는 병렬 계산이 가능하다. 게다가 구조도 직관적이기도 하다.

다만 문제는 태생이 메트릭스 연산을 위해서 탄생한 구조이다보니 나중에 컴퓨터 비젼관련 라이브러리에서 다룰때 종종 헷깔리게 된다. 이미지에서의 크기의 개념은 (가로 x 세로)이나 메트릭스에서는 (행, 열) 개념이기 때문이다. 이미지의 값을 numpy에 넣게되면 (세로, 가로) 느낌으로 사용하게 된다.

이때문에 초보자들은 여기서 많이 틀린다. 문제는 내가 모든 강의를 들은 것은 아니지만 대부분 주의 하고 외우세요 하면서 가르치시더라. 태생이 원래 수학적 접근의 차이라 다른것 뿐이지만 말이다. 사실 각 모듈의 태생의 목적을 알면 헷깔릴 일이 별로 없다. 깜박해도 금방 생각날테니 말이다.

그렇다 이 말 하려고 어그로 끌었다. "모듈의 태생을 알면 이유를 알 수 있다"

이제 배경을 알았으니 array shape을 받을 때 rows, cols, dim = np.array().shape 형태로 사용하는 것이 좀 더 덜 헷깔릴 것이다. 작지만 유용한 팁이라 할 수 있다.

덤 OpenCV 가 cv2 인 이유

덤으로 이글을 쓰는 시기에 OpenCV4가 사용되고 있다. 그럼에도 Python 에서는 cv2 라는 모듈 네임을 사용하고 있다. 대체 왜 그럴까? cv2 부터 C++이 도입되면서 OpenCV 코드들이 객체화가 되었다. 그리고 Mat 이라는 class 를 사용했었는데, Python 에서는 Mat 대신 numpy를 사용하지만, 둘이 사용법이 비슷하고 굳이 cv3 처럼 올릴 필요가 없다. 객체지향으로 개발하는 이유가 원래 이런 것들을 유지하려고 했던것이 아니었겠는가? 그리고 성능을 위해서 알고리즘은 여전히 C++로 구현되고 Java를 포함해서 Python에 wrapper 된 경우도 많다. 그리고 CV2라는 네임스페이스는 C++이 쓰는 것 아니었는가?

반응형
반응형

Multi-Progress 표시하기

작성 계기

이미지 유사도 검색 프로토타입 엔진을 만드는 과정에서 멀티 프로그래스를 사용하게 되었다. 문제는 검색을 하는 데이터가 많기 때문에 프로토타입 종료를 위한 테스트에 사용되는 데이터의 양이 많기 때문에 로드하는 데 생각보다 시간이 많이 걸린다.

문제는 설치 및 시연 시스템을 구축업무를 다른 사람이 어느정도 진행이 되고 있는지를 표시할 화면 필요하다. 그래서 찾던 중 스택오버플러우 형님의 코드를 확인하게 되었다. 문제는 원본 url을 메모를 안해서 잊어 버렸지만;;; 뭐 검색에 시간이 걸렸으니 다른 사람에게라도 도움이 되라고 기록으로 남긴다.

주의 사항

본래 curses 모듈은 유닉스 계열 터미널에서만 지원이 된다. 하지만, windows-curses 모듈을 pip로 설치를 하면, 해결이 된다. 모듈명 등 모든 것이 본래의 curses와 같아서 해당 모듈을 사용한 python 코드는 호환이 된다. 나중에는 내장 모듈로 이관되기를 희망한다.

>pip install windows-curses

예시 코드

import curses
import time

def report_progress(filename, progress):
    """progress: 0-10"""
    stdscr.addstr(0, 0, "Moving file: {0}".format(filename))
    stdscr.addstr(1, 0, "Total progress: [{1:10}] {0}%".format(progress * 10, "#" * progress))
    stdscr.refresh()

if __name__ == "__main__":
    stdscr = curses.initscr()
    curses.noecho()
    curses.cbreak()

    try:
        for i in range(10):
            report_progress("file_{0}.txt".format(i), i+1)
            time.sleep(0.5)
    finally:
        curses.echo()
        curses.nocbreak()
        curses.endwin()

참고 자료

반응형
반응형

임의의 progress status

작성 계기

tqdm 이라는 훌륭한 progress bar 렌더링 툴이 있지만, 구닥다리 환경에서 개발할 때 필요해서 약 10분정도 생각해서 임시로 만든 progress 상태를 표시해줌. 인터페이스는 대략 tqdm과 유사하게 작성을 하였고, 기본 generator 기능을 활용하여 구현하였음.

 

작성하고 보니 역시 프로그래밍 언어 부분의 발전은 개발자의 생산성 향상에 연결된다는 생각이 들었음.

예시

import time

def prog(jobs, desc=None):
    entire = len(jobs)
    progStr = "" if desc is None else desc
    progStr += " : [{} / {}]"
    for itN, itJob in enumerate(jobs):
        print(progStr.format(itN +1, entire), end="\r")
        yield itJob
    print()

if __name__ == "__main__":
    for it in prog(range(30), desc="잉여럭"):
        time.sleep(.5)
반응형

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

[python3]datetime, timestamp, str 변환  (0) 2021.06.07
[python3]Multi-Progress 표시하기  (0) 2019.12.23
[python3]깊은 폴더 생성(재귀호출)  (0) 2019.08.12
[Python3]selenium 모듈 에러 노트  (0) 2019.05.21
[python3]os.path 모듈  (0) 2019.05.04

+ Recent posts