1. 함수와 변수
프로그래밍에서의 함수는 불려진 시점에서 특정한 작업을 수행하며 입력값과 출력값은 있을 수도 있고 없을 수도 있습니다. 변수는 스스로 값을 가지기 보다는 다른 값을 가리키는 존재이다.
text = 'Hello'
print(text)
>> Hello
위의 코드에서 text는 변수, print는 함수가 된다. 파이썬에서 함수는 def로 정의되는 함수라고만 알고 있었는데 print와 같은 것들을 이미 만들어진 함수라고 한다는 것을 lms 공부를 하면서 처음 알게 되었다.
def로 정의되는 함수는 사용자가 직접 만드는 함수인데 이러한 함수는 내부에서 다른 함수를 부르거나 변수를 정의하는 등 다양한 직업을 할 수 있다.
def say_hello() :
print('Hello')
say_hello()
>> Hello
Hello라는 문자열을 출력하는 say_hello 함수를 만들고 아래에서 선언을 해주면 실행 시 Hello가 나온다.
def say_hello(name) :
print(name + ', Hello')
say_hello('Suji')
>>> Suji, hello
이와같이 함수에 인자를 전달할 수도 있다. 이때 인자는 여러개를 전달할 수도 있다.
def add_number(number1, number2) :
result = number1 + number2
print(result)
retrun result
print(add_number(1,2) + 3)
>>> 3
>>> 6
함수의 결과값을 return을 사용하여 반환할 수도 있다. 위와 같은 함수를 실행하면 함수 내에서 print를 한 3과 아래의 print에 의해 6이라는 결과가 나오게 된다.
2. 제어문 : if, while, for
- if 문 :
if 문은 if 조건문 : 형식으로 사용하며 : 이후 들여쓰기 된 코드 블럭의 내용은 조건문이 참일 때만 실행이 됩니다. 조건문에 사용되는 비교연산자에는 >(초과), <(미만), >=(이상), <=(이하), ==(같음), !=(다름) 등이 있다.
if 조건문 이외의 경우를 나타낼 때는 else : 를 사용한다.
조건문을 추가하기 위해서는 elif 조건문 : 의 형식으로 추가할 수 있다.
def print_number(number) :
if number >= 0 :
print("+")
elif number == 0 :
print('0')
else :
print("-")
print_number(1)
print_number(-1)
print_number(0)
>>> +
>>> -
>>> 0
- while 문 :
while문은 while 조건문 : 형태로 사용하며 조건이 참인 동안에 반복하는 반복문이다.
def fibonacci(n):
if n <= 2:
return 1
else:
return fibonacci(n-2) + fibonacci(n-1)
n = 1
while n <= 20:
print(fibonacci(n))
n = n + 1
>>> 1
1
2
3
5
8
13
21
34
55
89
144
233
377
610
987
1597
2584
4181
6765
위는 피보나치 수열을 코드로 작성한 것이다. 이를 실행시키면 조건문인 n이 20보다 작으면 반복문이 계속해서 수행되며 n이 20보다 큰 순간에 반복이 종료된다.
- for 문 :
for문은 for a in A : 형태로 사용되며 A에 따라 반복 횟수가 정해지기 때문에 A는 반복 가능한(iterable) 객체여야만 한다.
for i in "hello" :
print(i)
>>> h
e
l
l
o
위 코드에서 hello의 첫 글자인 h가 i라는 변수에 할당되고 이후에는 똑같이 한글자씩 print가 실행된다. hello의 길이는 5이기에 print가 5번 실행되었다.
+ for문을 좀 더 잘 사용하기 +
- enumerate()와 이중 for 문
for문만 사용하여 리스트를 출력하면 리스트의 요소만 출력이 되지만 출력되는 값들이 몇번째로 출력되는지 확인할 수 없다.
이때, enumerate()라는 기능을 이용할 수 있는데, enumerate()는 리스트, 문자열, 튜플 등이 있는 경우 순서와 리스트의 값을 함께 반환해주는 기능이다.
a_list = ['a','b','c','d']
for i in a_list :
print("값 : ", i)
>>> 값 : a
값 : b
값 : c
값 : d
for i, value in enumerate(a_list) :
print("몇번째 반복 : ", i, ", 값 : ", value)
>>> 몇번째 반복 : 0, 값 : a
몇번째 반복 : 1, 값 : b
몇번째 반복 : 2, 값 : c
몇번째 반복 : 3, 값 : d
- 이중 for 문
: for문 안에 for문을 또 사용하는 것을 이중 for문이라고 한다. 데이터의 양이 많을 때 for문이 많아지면 코드 동작 시간이 매우 길어져 이중 for문까지만 쓰는 경우가 많다. (이중 for문도 꼭 필요할 때가 아니면 굳이 쓰는 것은 좋지 않은 것 같다.)
a_llist = [a,b,c,d]
result = []
for i in range(2) :
for j in a_list :
result.append((i,j))
print(result)
>>> [(0, 'a'), (0, 'b'), (0, 'c'), (0, 'd'), (1, 'a'), (1, 'b'), (1, 'c'), (1, 'd')]
위의 코드를 실행하면 i 안에 j가 있기 때문에 . j에 대한 반복이 끝날 때 까지 i는 고정되는 것을 볼 수 있다.
+)
https://iambeginnerdeveloper.tistory.com/25
- 리스트 컴프리헨션 (list Comprehension)
: 리스트, 딕셔너리, 셋(Set) 등 순회형 컨테이너 객체로부터 이를 가공한 새로운 리스트를 생성하는 아주 간결하고 편리한 기능이다.
리스트 컴프리헨션을 사용하면 이중 for문으로 구현했던 내용을 단 한줄의 코드로 구현할 수 있다.
a = [a,b,c,d]
result = [(i,j) for i in range(2) for j in a_list]
print(result)
>>> [(0, 'a'), (0, 'b'), (0, 'c'), (0, 'd'), (1, 'a'), (1, 'b'), (1, 'c'), (1, 'd')]
- 제너레이터 (Generator)
: 제너레이터는 iterator를 생성해주는 함수이다. iterator는 next(0 메소드를 이용해 데이터에 순차적으로 접근이 가능한 객체이다. 제너레이터는 일반적인 함수와 비슷하게 보이지만 yield라는 구문이 가장 큰 특징이다.
제너레이터 함수가 yield를 만나는 순간 해당 함수는 그 상태로 정지되고 반환 값을 next()를 호출한 쪽으로 전달한다.
이후 일반적인 함수와는 달리 바로 종료되는 것이 아니라 그 상태를 계속 유지한다. 함수에서 사용된 데이터들이 메모리에 그대로 유지되는 것이다.
my_list = ['a','b','c']
def get_data_generator(my_list):
result_list = []
for i in range(2):
for j in my_list:
yield (i, j)
print('> 1 data loaded')
dt_generator = get_data_generator(my_list)
for X, y in dt_generator:
print(X, y)
>>>0 a
> 1 data loaded
0 b
> 1 data loaded
0 c
> 1 data loaded
1 a
> 1 data loaded
1 b
> 1 data loaded
1 c
>> 1 data loaded
위의 코드를 보면 값을 한번 반환 후 1 data loaded를 출력한다. 이는 2중 for문이 다 돌아가길 기다렸다가 처음부터 다시 돌아가는 구조가 아니라 yield를 통해 제너레이터 객체만 반환하고 for문에서 값을 하나씩 불러올 때만 데이터를 반환하는 것을 의미한다.
이를 통해 제너레이터는 메모리를 효율적으로 사용할 수 있다는 장점이 있다는 것을 알 수 있다. 데이터 양이 많을 때 그 데이터의 양 만큼의 리스트를 리턴받아 메모리에 전부 올려놓고 처리를 하는 것이 아니라 제너레이터를 활용해 현재 처리해야 할 데이터를 1개씩 로드하여 사용할 수 있다.
3. 자료형 : 정수, 부동소수점, 불리언, 문자열, 튜플과 리스트, 딕셔너리
- 정수형 int
: int는 양의 정수와 음의 정수 모두를 포함한다.
- 실수형 float
: 정수를 제외한 실수를 부동소수점 수 또는 떠돌이 소수점수인 float이라고 한다.
1은 int이지만 1.0은 float이 된다.
- booean, 'bool'
: 불리언 자료형에는 참(True)과 거짓(False)가 있다.
비교문에서 참/거짓 여부를 나타날 때 사용하는 자료형이다. None이거나 0일 때는 False로 반환되며 그 외 나머지 경우에는 True로 반환된다.
- 문자열 string
: 문자열은 따옴표 또는 쌍따옴표로 감싸서 표현해야 한다. 문자열도 글자가 여러 개 연속된 객체이기 때문에 for 루프를 사용할 수 있는 반복 가능한 객체이다.
반복 가능한 객체 중에서도 유일한 길이를 갖는 자료형인 컨테이너 자료형이기도 하다. 이러한 컨테이너 자료형들은 뒤에 [숫자]를 붙여 인덱스에 해당하는 값만 뽑을 수 있다.
a = 'Hello'
print(a[0])
>>> H
print(a[-1])
>>> o
- 튜플 tuple 과 리스트 list
: 튜플은 괄호 () 안에 원하는 값들을 쉼표(,)로 구분하여 사용한다.
리스트는 대괄호 [] 안에 원하는 값들을 쉼표(,)로 구분하여 사용한다.
튜플은 요소들을 변경할 수 없지만 리스트는 요소를 변경할 수 있다. 튜플과 리스트 모두 문자열 처럼 인덱스로 요소에 접근할 수 있다.
a = (1,2,3) #tuple
print(a[0])
>>> 1
b = [1,2,3] #list
print(b[0])
>>> 1
+)
https://iambeginnerdeveloper.tistory.com/23?category=904925
위의 for문 더 잘 사용하기 내용과 더불어 예외 처리, 멀티 프로세싱, 함수 사용법에 대해서 공부했다
.
1. 예외처리 Try-Except
: 예외처리는 코드를 수행하다가 에러가 발생했을 대 그 에러를 무시하게 하거나 에러 대신 적절한 처리를 해주게 하는 작업이다.
a = 5
b = 0
try:
print(a/b)
except:
print('에러가 발생했습니다.')
b = b+1
print("값 수정 : ", a/b)
>>> 에러가 발생했습니다.
값 수정 : 5.0 #에러가 발생했을 때 적절한 처리(b=b+1)를 거쳐 실행됨
2. 멀티프로세싱 Multiprocessing
: 컴퓨터가 작업을 처리하는 속도를 높여주는 방법 중 하나이다.
10명이 1개의 도구만 사용하여 하나의 일을 순차적으로 처리하는 것 보다 10명이 각각 1개씩 도구를 사용하여(총 10개의 도구) 일을 동시에 처리하는 것과 같은 느낌이다.
멀티 프로세싱에는 병렬처리(parallel processing)와 순차처리(serial processing)가 있다.
병렬 처리는 4개의 문자열이 동시에 처리가 되어 저장이 되지만 순차 처리는 문자열이 하나씩 차례대로 처리되어 저장되는 것을 볼 수 있다.
병렬처리를 위해서 multiprocessing 모듈을 import 해야한다.
import multiprocessing
def count(name):
for i in range(0, 100000000):
a = 1 + 2
print("completed : ",name)
num_list = ['p1','p2', 'p3', 'p4']
if __name__ == '__main__':
pool = multiprocessing.Pool(processes = 4)
pool.map(count, num_list)
pool.close()
pool.join()
>>> completed : p4
completed : p1
completed : p3
completed : p2
병렬 처리 시 4개의 프로세스를 사용하도록 하여 count 함수에 num_list의 원소들을 하나씩 넣는다.
병렬화 부분이 끝나면 close를 통해 새로운 작업을 추가하지 않게 된다.
join()은 병렬처리 작업이 끝날 때 까지 기다리도록 하는 구문이다.
3. 함수 사용법
: 함수는 위에서도 한번 설명했기에 간략하게 적고 넘어가겠다.
함수를 사용하면 코드의 효율성을 높여주고 코드의 재 사용성을 높여주기 때문에 개발하는 시간이 적게 걸린다는 장점이 있다. 함수를 사용하면 내가 짠 코드지만 모두가 이해하기 쉽기 때문에 코드의 가독성 또한 좋아진다.
- pass
: 함수 이름과 입력 정도만 먼저 만들어 놓고 구현은 나중에 해보겠다 하는 경우도 생기는데 이 때 pass를 사용하여 에러가 나지 않도록 할 수 있다.
def my_functioin() :
pass
물론 함수 안에 함수를 만들 수도 있고 2개 이상의 결과 값을 반환할 수도 있다.
- 람다 표현식 lambda expression
: 함수 이름이 없는 함수로 식 형태로 되어 있어 표현식이라고 부른다. 람다 표현식을 사용하는 가장 중요한 이유는 함수의 인수 부분을 간단히 하기 위힘이다.
def add(x,y) : return x+y
print((lanbda x,y : x+y)(10,20)
>>> 30