14 Feb 2020
|
python
05 함수
참고
애스크장고 AskDjango
함수
- 함수는 코드 중복을 제거하기 위해 사용된다.
- 구성
- 1개의 함수명 (필수)
- 0개 이상의 인자값 (선택)
- 1개의 반환값 (선택) 반환값이 없는 경우에는 None을 리턴한다.
함수 유형
- 인자 값, 반환 값 없는 함수
def myfn1():
result = 1 + 2
print(myfn1())
# 호출했지만, 반환값이 없어서 None 출력
- 인자 값은 있지만, 반환 값은 없는 함수
def myfn2(a, b, c):
result = a + b + c
print(myfn2(1, 2, 3))
# 호출해도 반환값이 없어서 None 출력
- 인자 값은 없지만, 반환 값은 있는 함수
def myfn3():
return 10
print(myfn3())
# 10 출력
- 인자 값과 반환 값이 모두 있는 함수
def myfn4(a, b, c):
result = a + b + c
return result
print(myfn4(1, 2, 3))
# 6 출력
Scope(변수의 유효 범위)
- 변수가 선언되어, 해당 변수가 영향을 미치는 영역
- 지역 변수(Local Variable): 함수 안에서 선언되어, 함수 내에서만 활용이 가능한 변수.
- 전역 변수(Global Variable): 함수 밖에서 선언되어, 함수 안에서도 활용이 가능한 변수.
전역 변수같은 경우에는 코드의 가독성을 헤치므로 권장하지 않는다. 지역변수를 사용하여 값이 변동되어도, 버그 발생 확률을 낮출 수 있다.
하지만, 상수문법이 없는 파이썬에서 변수명을 전부 대문자로 입력하여 관례적으로 상수처럼 사용하기도 한다.
Positional/Keyword Arguments
인자
함수가 실행되는데 필요한 0개 이상의 변수 목록
Positional Arguments
인자의 위치에 기반한 인자
def fn_with_positional_arguments(name,age):
print('이름: {} 나이: {}'.format(name,age))
fn_with_positional_arguments('Tom',10)
Keyword Arguments
- 인자의 이름에 기반한 인자
- 디폴트 인자 문법이 함께 적용
- 함수 호출 시에 해당 인자를 지정하지 않으면, 디폴트 인자값으로 값이 자동지정
- key를 입력하지 않으면 위치기반으로 적용된다.
def fn_with_keyword_arguments(name="", age=0):
print('이름: {} 나이: {}'.format(name,age))
# 키워드로 하면 순서 상관없다.
fn_with_keyword_arguments(name='Tom', age=10)
fn_with_keyword_arguments(age=10, name='Tom')
# 인자 지정하지 않으면, 디폴트 값으로 적용
fn_with_keyword_arguments(age=10)
fn_with_keyword_arguments(name='Tom')
# 키를 입력하지 않으면 위치 기반으로 적용
fn_with_keyword_arguments('Tom', 10)
기본 인자값은 함수가 실행될 때 계산되지 않고, 함수를 ‘정의’할 때 계산된다. 이러한 특성때문에 리스트나, 딕셔너리같은 mutuable한 데이터 타입은
문제를 일으킬 수 있다.
def buggy(arg, result=[]):
result.append(arg)
print(result)
처음 함수를 실행시에는 문제가 없어 보인다.
buggy(‘a’)
[‘a’]
두번째로 함수를 실행했는데, ‘b’만 출력되는 것이 아니라 그 전의 ‘a’의 값도 남아 있는 것이다.
buggy(‘b’)
[‘a’,’b’]
위에서 말했듯이, 기본 인자값은 정의 시 계산되기 때문에, result=[]는 메모리 어딘가에 지정이 되어있다.
그리고 리스트나 딕셔너리같은 mutuable 데이터 타입은 해당 메모리의 값을 변경할 수 있기 때문에 값을 변경해도 같은 메모리 주소에 반영이 된다.
그렇기에 위처럼 계속 기록이 되는 것이다.
위의 상황을 해결하긴 위해서 다음과 같이 작성해야 한다.
def nonbuggy(arg, result=None): #result를 None으로 지정
if result is None:
result = []
result.append(arg)
print(result)
Packing
인자의 개수를 제한하지 않고, 다수의 인자를 받을 수 있음
다수의 Positional Arguments를 하나의 tuple로 받는다.
def fn2(*colors):
for color in colors:
print(color)
fn2()
fn2('white')
fn2('white','yellow')
fn2('white','yellow','black','pink')
def fn3(color1, color2, *other_colors):
print('color1:', color1)
print('color2:', color2)
for color in other_colors:
print(color)
# 최소 2개의 인자 지정이 필요하다. 부족하면 TypeError
fn3('brown') # TypeError 발생
fn3('brown','green')
fn3('brown','green','white')
fn3('brown','green','whilte','yellow')
Unpacking
인자를 넘길 때 Sequence Data Type(리스트/튜플 등)을 다수의 인자인 것처럼 나눠서 전달 가능
colors = ['white', 'yellow', 'black']
fn2(*colors) #white, yellow, black으로 3개 전달
fn2('brown','pink',*colors)
#brown, pink, white, yellow, black으로 5개 전달
other_colors = ('violet', 'coral', 'cyan')
fn2('brown', 'pink', *colors, *other_colors)
#brown, pink, white, yellow, black, violet, coral, cyan
fn3('purple', *('aqua', 'beige', 'black'))
#purple, aqua, beige, black 튜플도 언패킹 가능
익명함수 (Anonymous Function)
lambda를 사용하여 익명 함수를 사용할 수 있다.
- return문을 쓰지 않아도, 마지막 값을 리턴값으로 처리
- 대개 인자로 1줄 함수를 지정할 때 많이 쓰임.
- 일반 함수와 인자처리도 동일하게 처리된다.
# 인자 두 개를 받고 x + y 값은 반환하는 의미이다.
(lambda x, y: x + y)(1,2) # 바로 실행할 때
mysum3 = lambda *args: sum(args) # mysum에 할당
print(mysum3(1,2,3,4,5,6,7) # 28
1급객체
다른 객체들에 적용 가능한 연산을 모두 지원하는 객체
- 인자로 넘기기, 변수에 대입하기 등
- 종류: 일급 함수/클래스/컨트롤/타입/데이터타입 등
파이썬은 1급 함수/클래스를 지원한다.
- 함수/클래스를 런타임에 생성 가능.
- 함수/클래스를 변수에 할당이 가능
- 함수/클래스를 인자나 리턴값으로서 전달 가능.
익명함수를 mysum1에 할당하고 이를 또 mysum2에 할당해도 잘 실행 된다.
mysum1 = lambda x, y: x + y
mysum2 = mysum1
mysum2(10,20) -> 30
함수를 인자로 받아 호출할 수 있다.
def myfn(fn, x, y):
return fn(x,y)
myfn(mysum1, 10, 20) -> 30
myfn(lambda x,y:x*y, 10,20) -> 200
# 익명함수를 인자로 가능하다.
# 추후에 데코레이터에서 유용하게 사용할 수 있다.
고차함수 (Hign Order Function)
다른 함수를 생산/소비하는 함수
다른 함수를 인자로 받거나, 그 결과로 함수를 반환하는 함수
def base_calculator(base):
wrap = lambda x, y: base + x + y
return wrap
calc_10 = base_calculator(10)
# 이렇게 하면, calc_10은 lambda x, y: 10 + x +y의 함수를 가지게 된다.
calc_10(1,2) # 13
calc_10(10,20) # 40
14 Feb 2020
|
python
04 제어문
참고
애스크장고 AskDjango
조건문
if/else를 통해 참/거짓을 판별하여 흐름을 제어할 수 있다.
if 조건식:
print("참이면 여기!")
else:
print("거짓이면 여기!")
elif 추가해서 더 많은 경우로 나눌 수 있다.
score = 80
if score > 80:
print("A")
elif score > 60:
print("B")
else:
print("C")
반복문
Iterable(반복가능한) Object로부터 가져올 값들을 모두 가져올 때까지 반복
for 변수 in Iterable Object
:
- 매 항목마다 수행할 코드 블록
- 반복하다가 break문을 통해 반복문을 빠져나올 수 있다.
- 또는 continue문을 통해 건너뛰고 위에서부터 진행할 수 있다.
기본
for i in range(20): # 0에서 19까지 순회
print(i)
# 19까지 출력하면 더 이상 순회할기 없기에 위 반복문은 종료된다.
break
if문을 곁들여 조건에 성립하면 break하여 for문을 종료한다.
for i in range(20): # 0에서 19까지 순회
print(i)
if i > 10: #i가 10을 초과하면 종료한다.
break
continue
if문을 곁들여 조건에 성립하면 건너뛰고 위에서 다시 시작한다.
for i in range(20): # 0에서 19까지 순회
if i % 2 == 0: # 짝수인 숫자는 건너뛰고 다시 위에서 시작
continue
print(i)
중첩 반복문
이중 for문이라고도 불리는데, 2차원 리스트, 튜플 활용할 때 아주 중요하다.
for i in range(2,10):
for j in range(1,10):
print(i, j)
break
반복문 내에서의 break는 근접한 반복문만 종료시킨다.
즉, 두 번째에서 1을 출력하고 종료하고
다시 위로 올라가 i는 i+1가 되고를 반복한다.
결과
2 1
3 1
4 1
5 1
6 1
7 1
8 1
9 1
중첩 반복문을 한 번에 종료시키려면, 예외를 발생시키거나 함수 내에서 return문을 발생시켜야 한다.
def gugu():
for i in range(2,10):
for j in range(1,10):
print(i, j)
return None
gugu()
2 1
출력 후 종료
for문을 사용하게되면 range함수를 자주 접하게 된다.
range함수는 문법적으로는 리스트가 아니라 Iterable(순회가능한) 객체이다.
while
while문도 for문처럼 반복을 수행한다.
while 조건:
매 항목마다 수행할 코드 블록
i = 0
while i < 20:
print(i)
if i > 10:
break
i += 1
반복문은 무한 루프를 구성 시 용이하다.
반복문 조건을 항상 True로 하면 된다.
while True:
if로 특정 조건을 충족하면 break로 종료하면 된다.
for문에서 무한루프를 원한다면, itertools.count 함수를 통해 호출한다.
from itertools import count
for i in count(1):
print(i)
if i > 60:
break
i는 1부터 증가한다.
연습문제
2, 4, 6, 8단 구구단 출력하기
# range(start,stop,step) step에 2를 입력하여 2씩 넘어간다.
for i in range(2,9,2):
for j in range(1,10): # 1~9 곱할 수
print(i*j, end=' ')
# i*j 곱한 수 출력
# end 값을 스페이스 한칸을 주어 줄바꿈을 안하고 한 칸 띄어 출력한다.
print() # 다음 단을 위해 한 번 줄바꿈 한다.
14 Feb 2020
|
python
03 list, tuple, dictionary 정리
참고
애스크장고 AskDjango
여러 원소들을 가지고 있는 자료 구조
- list, deque
- set, fronzensets
- dict, defaultdict, OrderedDict, Counter
- tuple, namedtuple
- **str
list생성
- 생성문법: [], list(), list(iterable)
- 여러 값을 순차적으로 저장, 순서를 보장
- 리스트를 한 줄로 쓸 때에는 대개 끝에 쉼표를 쓰지 않음
- 여러 줄로 나누어 쓸 때에는 항목 추가/삭제를 용이하게 하기 위해 끝에 쉼표를 쓴다.
numbers= [1,3,5,7,9]
names = [
'Tom',
'Steve',
'Min',
]
- 색인(index)지원: 0부터 시작하여 1씩 증가
- numbers[0] 은 위의 numbers 리스트에서 맨 처음 항목(1)을 가르킨다.
- 음수 색인 지원: -1은 맨 끝에서부터를 의미한다. -2는 끝에서 두 번째.
- numbers[-1]는 numbers 리스트에서 9를 의미한다.
- 다른 타입의 값들로도 구성 가능
- a=[1,’1’,’2’,2] 이런식으로 가능 dict형, tuple형 들 여러 자료형을 넣을 수 있다.
- 가급적 같은 타입으로 맞춰주는게 가독성 면에서 좋다.
list 메서드
- numbers.append(값): numbers리스트 마지막에 값을 추가한다.
- numbers.pop(공란 or 색인값): 공란인 경우 numbers 리스트의 마지막 값을 삭제하고, 색인값을 입력한 경우에는 해당 색인의 값을 삭제한다.
- numbers.remove(값): numbers리스트에서 왼쪽부터 최조 발견된 값을 삭제한다. [1,2,3,2]일 때 remove(2)를 실행하면 맨 처음 2를 삭제한다.
- numbers.insert(색인값,값): numbers리스트에서 색인값 위치에 값을 추가함. [1,2,3,2]일 때 insert(1,11) 1번 자리에 11값을 삽입함. -> [1,11,2,3,2]
슬라이스 하기
[시작인덱스:끝인덱스]
를 통해 원하는 부분을 잘라 활용할 수 있다.
numbers=[1,2,3,4,5,6,7,8,9,10]
print(numbers[1:]) #1번째부터 끝까지 출력
# [2,3,4,5,6,7,8,9,10] 출력
print(numbers[1:7]) #1번째부터 6번째까지 출력. 7미만이라 이해하면 될듯
# [2,3,4,5,6,7]
print(numbers[1:7:2]) #1번째부터 6번째까지 2씩 증가하여 출력.
#[2,4,6]
print(numbers[::-1]) #반대로 출력, 은근 쓰이니 기억하기!
#[10,9,8,7,6,5,4,3,2,1]
리스트 합치기
numbers1 = [1,3,5,7]
numbers2 = [2,4,6,8]
print(numbers1+numbers2)
[1,3,5,7,2,4,6,8]
List Comprehension
numbers1 = [1,3,5,7]
numbers2 = [2,4,6,8]
print([i + j for (i, j) in zip(numbers1, numbers2)])
# [3,7,11,15]
zip함수는 동일한 개수로 이루어진 자료형을 묶어주는 역할을 한다.
list(zip([1,2,3],[4,5,6]))
[(1,4),(2,5),(3,6)]
#이런식으로 첫번째 값, 두번째 값끼리 묶어주는 역할을 한다.
# 개수가 안맞으면, 맞는데까지만 묶어준다.
tuple
생성방법: (), tuple(). tuple(iterable)
list와 비슷하지만 tuple에 저장된 값은 변경할 수 없다.
numbers= (1,3,5,7) 일 때, numbers[0]=10 시도해보면 에러가 발생한다.
소괄호()안에 어떻게 입력하냐에 따라 우선순위 연산자 혹은 튜플이 된다.
tuple1 = (1 + 3) # 우선순위
tuple2 = (1 + 3,)# 튜플
tuple3 = (3)# 우선순위
tuple4 = (3,)# 튜플
즉, 콤마(,)를 쓰냐 안쓰냐에 따라 정해진다.
set
중복을 허용하지 않는 데이터의 집합
list/tuple의 중복을 제거할 때 유용하다.
set_numbers={1,3,4,5,1,4,3,1} 중괄호{}를 사용하여, 내용 중 중복이 있으면 제거
set_numbers
{1,3,4,5}
list_numbers = [1,1,2,1,1,2,2,3,1,2,3]
list_numbers = list(set(list_numbers)) set함수를 이용해 중복을 제거하고 다시 list함수를 사용하여 리스트화
list_numbers
[1,2,3]
합, 교, 차, 여집합 사용하기
set_numbers1 = {1,3,4,5,1,4,3,1}
set_numbers2 = {1,3,4,11,13,14,15,11,14,13,11}
print(set_numbers1 - set_numbers2) 차집합
print(set_numbers1 + set_numbers2) 합집합
print(set_numbers1 & set_numbers2) 교집합
print(set_numbers1 ^ set_numbers2) 여집합
사전형 (dict)
- key와 value의 쌍으로 구성된 집합
- key 중복을 허용하지 않음.
- 중괄호 내에 콜론 (:)으로 key/value를 구분
dict_values = {‘blue’:10, ‘yellow’:3, ‘blue’:9, ‘red’:7}
- in 연산자로 멤버쉽 체크 지원 (Key의 등록 여부)
- 순회(for) 시에는 key 목록만 순회
- 멤버함수
- .keys(): key 목록
- .values(): value 목록
- .items(): (key,value) 목록
14 Feb 2020
|
python
02 변수 및 데이터 타입
참고
애스크장고 AskDjango
변수(Variables)
- 프로그램이 실행되면서 필요한 데이터를 임시로 저장하는 공간
- 효율성을 높이기 위해 적절한 크기/ 용도의 변수에 값을 담아서 처리
- 하나의 소프트웨어가 동작하면서, 로직에 따라 수많은 새로운 변수가 생겨나고 변경되며 제거
파이썬은 메모리상에 값이 존재하고, 변수가 참조하는 형태라고 하는데, 이 부분은 더 공부해서 정리해봐야겠다.
예시로는
a=3
b=3
id(a), id(b)를 출력해보면 동일한 주소값이 표시된다.
데이터 타입(Data Types)
- 변수는 하나의 데이터를 담아두는 그릇 같은 개념이다.
- 용도에 따라 그릇이 다르듯, 용도에 맞게끔 활용하여 효율성을 높여야 한다.
- 자원은 유한하다는 것도 알아두자.
숫자 (Numeric Type)
- 정수형: int
- 실수형: float
파이썬2에서는 int, long, float, double형이 존재했는데, 파이썬3로 넘어가면서 int/float로 통합되었다 한다.
명시를 중요하는 개발자 입장에서는 별로 좋아하지 않을거 같은데, 나는 파이썬으로만 공부해서인지, 현재까지는 이게 편한다.
수의 범위 제한이 없다는데, 잘못 쓰면 메모리를 남용할 수 있을거 같다.
참/거짓 (Boolean)
나중에 배울 제어문은 참/거짓을 통해서 프로그램의 동작을 다양하게 할 수 있다.
- 참 - True
- 거짓 - False
비교연산자를 활용하여 Boolean 값을 받아올 수 있다. 이것을 통해 향후 조건문이라던가 반복문에서 활용할 수 있다.
비교 연산자 종류
- <, <=, >, >=, ==, !=
- is, is not
논리 연산자
bool() 함수를 이용하여 참/거짓을 출력할 수 있다.
- 0은 False, 이 외에는 True
bool(0) -> False
bool(-1) -> True
- 빈 문자열은 False, 이 외에는 True
bool('') -> False
bool(' ') -> True
스페이스도 문자열이다!
- 빈 list/tuple/set/dict는 False, 이 외에는 true
bool([]) -> False
bool([' ']) -> True
문자열 (String)
홑(‘)따옴표나 쌍따옴표(“)로 감싸진 애들은 문자열이다.
name1 = ‘Python’
name2 = “Python”
I’m seokju를 출력하기 위해서 ‘I’m seokju’로 입력하면 오류가 발생한다.
이럴 경우에는 백슬래쉬()를 활용한 이스케이프처리를 해주거나 쌍따옴표로 감싸주고 ‘를 쓰면 된다.
- 이스케이프: ‘I\‘m seokju’
- 쌍따옴표: “I’m seokju”
홑(쌍)따옴표를 3개로 감싸주면, 여러 줄 문자열을 지원한다.
test = '''
Hi
I'm
Seokju
'''
문자열 형식 지정자
문자열 내에 {}
와 같은 형태로 슬롯을 만들고 format함수를 통해 슬롯에 필요한 데이터를 남길 수 있다.
format함수에 함수인자로서 슬롯을 지정하는 방법은 위치(Positional), 키워드(Keyword) 방법이 있다.
위치 인자 (Positional Arguments)
# a, b, c 출력. format의 맨 처음 인자가 {0} 순으로 입력이 된다.
'{0}, {1}, {2}'.format('a','b','c')
#a, b, c 출력. 부여된 번호가 없어 순서대로 입력
'{}, {}, {}'.format('a','b','c')
# c, b, a 출력. - format인자가 0번째부터 시작하기 때문이다.
'{2}, {1}, {0}'.format('a','b','c')
# c, b, a 출력. 언패킹이라는 건데, 추후 설명
'{2}, {1}, {0}'.format(*'abc')
# 에러 발생 - 숫자만큼 인자 개수 맞춰줘야 한다.
'{0}, {1}, {2}'.format('a','b')
키워드 인자 (Keyword Arguments)
'{lat}, {lng}'.format(lat='37.24N', lng='-115.81W')
#딕셔너리 언패킹을 통해 출력
coord ={'lat':'1234', 'lng':'4444'}
'{lat}, {lng}'.format(**coord)
14 Feb 2020
|
python
01 print 함수 정리
- 가장 기본적인 출력 함수
- Seperator, End 옵션 사용
- Fromat 형식 출력
# 기본 출력 결과 같음
print('Hello python') #작은 따옴표
print("Hello python") #큰 따옴표
# 세개로 묶으면 여러줄을 출력할 수 있다.
print("""Hello
python""") # 새개로 묶기
print('''Hello
python''') # 세개로 묶기
seperator 옵션 사용
print(3, 4)
이런식으로 입력하면 결과로는
3 4
숫자 사이가 공백으로 나눠진다.
print의 sep 키워드를 활용하면 공백 대신에 다른 문자를 삽입할 수 있다.
3,4
이런식으로 활용할 수 있다.
print('test', 'gmail.com', sep='@')
test@gmail.com
end 옵션 사용
파이썬의 print()
는 기본적으로 출력 후 다음줄로 이동된다.
기본적으로 끝에 \n 이 포함되기 때문이다.
이것은 end
옵션을 사용하여 변경할 수 있다.
end 옵션 사용 전
print(3) # 기본으로 \n(개행)이 있기에 줄바꿈이 이뤄진다.
print(4)
3
4
end 옵션 사용 후
print(3, end='') # end 값으로 원하는 값 삽입 가능
print(4, end='')
34
유동적인 값을 출력하는 기능으로 format
함수가 있다.
print('{} and {}'.format('test', 'best'))
# 중괄호에 맞게끔 인자를 줘야한다.
# 순서에 맞게 표시가 된다.
test and best
번호를 추가하여 순서를 줄 수도 있다.
print('{0} and {1} and {0}'.format('a', 'b'))
# 0과 1 2개의 숫자만 있기에 format함수 안에는 2개의 인자만 넣어야 한다
a and b and a
숫자가 아닌 키값으로도 할 수 있다.
print("{a} are {b}".format(a='You', b = 'Me'))
# a에 You b는 Me 할당
You are Me
%s, %d, %f
포맷팅 사용
%s : 문자
%d : 정수
%f : 실수
print("%s's number: %d" % ('serven', 7))
seven’s number: 7
print("Test1: {0: 5d}, Price: {1: 4.2f}".format(776, 6543.123))
# 정수는 다섯자리로 표시, 실수는 소수점 둘째자리까지만 표시
Test1: 776, Price: 6543.12
print("Test1: {0: 05d}, Price: {1: 4.2f}".format(776, 6543.123))
# 5d앞에 0을 붙히면 남은자리는 0으로 채운다는 얘기이다
Test1:00776, Price: 6543.12