240717 파이썬반
1. 함수를 왜 쓸까?
def 함수 : 재사용을 위함. 가독성. 유지 보수.
(인자값만 바꿔서 재사용 가능)
2. 함수의 구조
input x , output f(x)
input == parameter
output == return value
함수란 논리적인 어떤 결과를 내는 것이다
3. 함수의 정의
def(ine) 키워드로 시작함
return == 종료시점 #모든함수는 동작 원리상 return None 자동 출력됨 ✔✔✔
# def 뒤 함수이름(매개변수==input 몇개인가):
def greet(name) :
"""입력된 이름 값에
인사를 하는 메세지를 만드는 함수"""
#docstring(설명서) #써도되고선택임
return message #return은 반드시 작성이 필요한 것은 아니다
#return == 종료시점 #모든함수는 동작 원리상 return None 자동 출력됨 ✔✔✔
result = greet('Alice') # call : 호출 #greet() #호출된 반환값이 result에 할당됨
독스트링은 함수 선언 시, def 바로 다음 줄에서 시작해서 첫 줄에는 함수의 목적을,
다음 단락부터는 세부적인 함수의 동작에 대한 설명이나 인자, 반환 값 그리고
외부에서 처리되어야 하는 예외에 대해서 설명하는 주석을 말함
(*함수 뿐만 아니라 나중에 배울 클래스, 패키지등 설명할때도 사용)
으 아래 헷갈려 ✔ ✔ ✔ ✔
def make_sum(p1, p2):
return p1 + p2
result = make_sum(3, 4)
return_value = print(result)
print(return_value) #None #print()는 return이 없는 함수이다 ✔✔✔✔
#즉 리턴과 출력은 다른 개념이다 ✔✔✔✔
def my_func():
print("bye")
result = my_func()
print(result)
#bye
#none
4. 매개변수와 인자
매개변수 : 정의할 때 쓸 수 있음. 정의할 때 함수가 받을 값을 나타내는 변수임 (parameter)
인자 : 함수를 호출될 때 실제로 전달되는 값 (argument)
매개변수 != 인자
def add_num(x,y): #x, y는 매개변수
result = x+y
return result
a = 2
b = 3
sum_result = add_num(a,b) #인자
print(sum_result)
그리고 다양한 인자 종류가 있는데..
1) 위치인자( positional argument)
위치에 따라 결과에 영향을 주는 인자로 위치인자는 함수 호출 시 반드시 값 전달 필요 ✔
def greet(name, age):
print(f'안녕하세요, {name}님, {age}살이시군요')
greet('Harry', 24)
#안녕하세요, Harry님, 24살이시군요
greet('Harry') # TypeError: greet() missing 1 required positional argument: 'age'
greet(29, 'Harry') #안녕하세요, 29님, Harry살이시군요
2) 기본 인자값(default argument values)
함수 정의에서 매개변수에 기본값을 할당하는 것
함수 호출시 인자를 전달하지 않으면 기본값이 매개변수에 할당됨
def greet(name, age= 30):
print(f'안녕하세요, {name}님, {age}살이시군요')
greet('Harry')
#greet('Harry', 24) #사용자 입력값으로 대체
3) 키워드 인자
함수 선언시 인자의 이름과 함께 값을 전달하는 인자
함수 선언시 꼭 위치 인자 뒤에 위치할 것 ✔✔✔✔✔✔✔✔✔✔✔✔✔✔✔✔
-키워드 인자 : 순서 상관없음(장점)
def greet(name, age= 30):
print(f'안녕하세요, {name}님, {age}살이시군요')
#greet(name = 'Harry', age = 23)
greet(age =34, 'Harry') #오류
#greet(age =34, name = 'Harry')# 키워드 인자 : 순서 상관없음(장점)
#greet('Harry')
4) 임의의 인자 목록(0개 이상)
함수 정의시 매개변수 앞에 *를 붙여 사용, 여러개 인자를 (안전하게) tuple로 처리
*tuple : 개발자가 직접 쓰기보다 파이썬 내부적으로 동작할 때 쓰이는 dtype
*print()도 임의의 인자 목록을 지님 -> 그렇기에 몇개를 넣어도 출력되는 것
# 4. Arbitrary Argument Lists
def calculate_sum(*args):
print(args)
print(type(args))
calculate_sum(1,100,50000, 2000, 30)
#(1, 100, 50000, 2000, 30)
#class 'tuple'>
아래 주의 ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔
-위치 인자가 앞에 올 것
# 4. Arbitrary Argument Lists
def calculate_sum(*args,params): #틀림 #위치인자는 앞으로 올것
print(args)
print(type(args))
calculate_sum(1,100,50000, 2000, 30)
# 4. Arbitrary Argument Lists
def calculate_sum(params,*args): #위치인자는 앞으로 올것 # 1이 위치인자가 됨 ✔ ✔ ✔ ✔ ✔ ✔ ✔
print(args)
print(type(args))
print(params)
calculate_sum(1,100,50000, 2000, 30)
#(100, 50000, 2000, 30)
#<class 'tuple'>
#1
5) 임의의 키워드 인자 목록
함수 정의시 매개변수 앞에 **를 붙여 사용, 여러개의 인자를 dict로 묶어 처리 ✔ ✔ ✔
# 5. Arbitrary Keyword Argument Lists
def print_info(**kwargs):
print(kwargs)
print_info(name='David', age = 20) #key,value 입력
#{'name': 'David', 'age': 20}
6) 함수 인자 권장 작성순서
위치 -> 기본 -> 가변 -> 가변 키워드
*매번 모든 인자를 다 쓰진 않음
# (굳이) 인자의 모든 종류를 적용한 예시
def func(pos1, pos2, default_arg='default', *args, **kwargs):
print('pos1:', pos1)
print('pos2:', pos2)
print('default_arg:', default_arg)
print('args:', args)
print('kwargs:', kwargs)
func(1, 2, 3, 4, 5, 6, key1='value1', key2='value2')
# pos1: 1
# pos2: 2
# default_arg: 3
# args: (4, 5, 6)
# kwargs: {'key1': 'value1', 'key2': 'value2'}
5. 재귀 함수
자기자신을 그냥 호출하면 무한반복이 된다
그래서 종료될 수 있게 n-1, 팩토리얼을 쓰는것
*근데 팩토리얼 없이도 물론 쓸 수 있음.
- 상황에 따라 반복문보다 코드 간결해짐
def factorial(n):
if n==0: #종료조건
return 1
else:
return n*factorial(n-1)
print(factorial(3)) # 6
#3*f(2) == 3*2*1*1
#2*f(1)
#1*f(0)
6. 내장 함수(Built-in function : 이미 준비된, built in)
ex. print(), len(), min(), sum(), sorted(reversed= True *키워드인자)
-유용한 내장함수 :
1) map :
map(function, iterable)
iterable : 반복가능한 객체(ex. collection : 리스트, 튜플, 딕셔너리 등)
iterable 요소 하나하나에 function 적용하게 하는 map()
function : 내가 새로 정의한 함수도 포함 -> 확장성 어마어마~
2) zip : ✔ ✔ ✔ ✔ ✔ ✔
zip(*iterables) -> (반복이 가능한 친구들을) 임의의 인자로 받는군
(파이썬이 임의로 묶는) 튜플로 반환
그럼 언제 쓸까 ?
- 여러 개의 리스트 동시에 조회할 때
scores = [
[10,20,30],
[40,50,29],
[30,20,13]
]
# 행렬에서 열끼리 작업이 필요할 때
for score in zip(*scores):
print(score)
7. python의 범위(scope)
함수 코드 내부에 local scope, global scope 개념을 살펴보자
-범위와 변수 관계
-scope :
1) global scope : 코드 어디에서든 참조 가능한 공간
2) local scope : 함수가 만든 scope(함수 내부에서만 참조 가능)
*함수 내에서 바깥 scope에 접근은 가능하나 수정 불가 ✔
def func():
num =30
print('local', num) #local 30
func()
print('global', num) #NameError, num is not defined
예제 하나 더
num = 0 #global
def increment():
global num #num을 전역변수로 선언해준 것
num += 1
print(num) # 0 # 아직 함수실행안함
increment()# 함수실행
#print(num) # 1
아래 답 모게?????????? ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔
a = 1
b = 4
def enclosed():
a = 10
c = 3
def local(c):
print(a, b, c) #
local(500)
print(a, b, c) #
enclosed()
print(a, b) #
답
# 10 4 500 #내부에 없으며 한단계씩 위로 찾아감!!
# 10 4 3
# 1 4 #작은 쪽 영역에서 찾진 않는다!!
이건 답 모게
a = 1
b = 4
def enclosed():
global a
a = 10
c = 3
def local(c):
print(a, b, c) #
local(500)
print(a, b, c) #
enclosed()
print(a, b) #
10 4 3
10 4
-'global' 키워드
-내부에서 global로 선언시 전역 범위로 사용 가능
단,
1) 키워드 선언 전에 참조 불가 ✔ ✔ ✔ ✔ ✔ ✔
2) 매개변수로 global 키워드 사용 불가
#%%
num = 10
def increment():
print(num) #SyntaxError: name 'num' is used prior to global declaration
global num # 값을 바꾸려할 때 선언
num = 3
increment()
print(num)
#%%
num = 10
def increment():
print(num) #10
#global num #참조만 하려면 global 안써도 됨, 값을 바꾸려할 때 선언
#num = 3
increment()
print(num) #10
#%%
num = 10
def increment():
#print(num) #10
global num #바꿀게요 선언
num = 3
increment()
print(num)
# 3
다른 예제
# map : iterable(리스트)한 객체를 통해 새로운 iterable(리스트)를 만들고 싶을때
names = ['홍길동', '임꺽정', '김무아']
ages = [20,30,25]
# 딕셔너리 형태로 바꿔서 리스트로 저장
no = 0
def create_user(name, age):
global no # 0으로 바꾸고 ✔ ✔ ✔ ✔
no += 1
return {'번호':no, '이름':name, '나이':age}
members = list(map(create_user, names, ages))
print(members)
8. packing, unpacking
packing : 여러개의 값을 하나의 변수에 묶어서 담는 것
1) 변수에 담긴 값들은 튜플 형태로 묶임 -> 파이썬 자체적
2) *을 활용한 패킹
packed_values = 1,2,3
print(packed_values) #(1,2,3)
아래 *는 *b는 남은 요소들을 리스트로 패킹하여 할당 ✔ ✔
num = [1,2,3,4,5]
a , b* ,c = num
print(a) # 1
print(b) # [2, 3, 4]
print(c) # 5
함수로 표현해보면
def my_func(*obj):
print(obj) # (1, 2, 3, 4, 5)
print(type(obj)) # <class 'tuple'>
my_func(1, 2, 3, 4, 5)
# (1, 2, 3, 4, 5)
# <class 'tuple'>
unpacking
1) 예제
packed_values = 1,2,3,4,5,6
a,b,c,d,e,f = packed_values
print(a,b,c,d,e,f)
2) *는 리스트 요소(반복 가능한 객체)를 언패킹해서 인자로 전달 ✔ ✔ ✔ ✔
def my_func(x,y,z):
print(x,y,z)
names = ['a', 'b'. 'c']
my_func(*names) #a b c
3) **을 활용한 언패킹 ✔ ✔ ✔ ✔
딕셔너리 키-값 쌍을 언패킹하여 함수의 키워드 인자로 전달
def my_func(x,y,z):
print(x,y,z)
names = ['a', 'b', 'c']
names2 = {'z':'c', 'x':'a', 'y':'b'} #딕셔너리일때는 키값과 매치되는 거라 순서가 상관없음
my_func(*names) #a b c
my_func(**names2) #a b c
9. 람다 표현식
1) 익명 함수를 만드는 표현식
2) 한줄로 간단한 함수를 정의
lambda 매개변수 : 표현식
*매개변수 여러개일땐 , 쉼표로 구분
*표현식 : return 포함
def add(x,y):
return x_y
result = add(3,2)
print(result) # 5
짜자잔
add = lambda x, y : x+y
result = add(3,2)
print(result) #5
어라 간결해보이지도 않는데 언제 씀? ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔
1) map 함수와 함께 씀
2) 일회성 함수로 씀(def 함수는 재사용 가능이 특징)
예제 ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔
#%%
# 람다 활용
radius =[1,2,5, 10] # 반지름 리스트
print(sorted(radius)) #오름차순 정렬
print(sorted(radius, reversed = True)) # 내림차순
# 원의 넓이 순으로 정렬
print(sorted(radius, key=lambda r:r**2*3*14))
# 람다식으로 정렬 조건 만들 수 있다
#사각형 예제
rects = [(1,2), (3,3), (1,1), (10,9)] #[(가로, 세로),]
print(sorted(rects)) #가로길이순 정렬
print(sorted(rects, key=lambda rect: rect[1])) #세로 길이순 오름차순 정렬
print(sorted(rects, key=lambda rect:rect[0]*rect[1])) #사각형 넓이순 정렬
# 정렬 조건 세분화 가능
# 정렬값이 동일한 경우 그 다음 정렬 조건으로 설정
# ex. 가로 길이 오름차순으로 정렬(가로길이 동일하면 세로 길이 내림차순 정렬)
print(sorted(rects, key=lambda rect:(rect[0], -rect[1])))
#원본 리스트 수정 여부
rects.sort() #원본 리스트를 정렬
print(rects)
print(rects.sort()) #None # return 값 없음
#.sort() : 메소드 # sorted : 함수
헷갈리는 거 수업복습
#1. split() 내장함수
# string.split(seperator, maxsplit)
# str에 적용되는 함수
# 구분자를 기준으로 나눠서 리스트로 전환
# 1) .split() : 아무런 파라미터 넣지 않고 실행시, 띄어쓰기 혹은 개행문자에 맞춰 분할
ex = 'a b c d'.split()
print(ex) #['a', 'b', 'c', 'd']
# 2) 예제
ex1 = int(343).split()
print(ex1)
#AttributeError: 'int' object has no attribute 'split'
ex2 = str(343).split()
print(ex2) #['343']
ex3 = 'hello world'.split(' ')
print(ex3) #['hello', 'world']
ex4 = '1a2a34da5a23'.split('a')
print(ex4)
# 내 답 ['1', 'a', '2', 'a', '34d', 'a','5', 'a', '23']
# 정답 ['1', '2', '34d', '5', '23']
ex5 = 'apple.banana.grape'.split('.',1) #구분자, 최대분할횟수
print(ex5)
# 3) .map()와 함께 쓸 때
# .map(함수, 리터러블)
num_1, num_2 = map(int, input().split())
print(num_1)
print(num_2)
num_3 = list(map(int, input().split()))
print(num_3)
## ------
#2. zip 내장함수
scores = [
[10,20,30],
[40,50,29],
[30,20,13]
]
#행렬에서 열끼리 작업이 필요할 때
for score in zip(*scores):
print(score)
#(10, 40, 30)
#(20, 50, 20)
#(30, 29, 13)
# ---
#3. 함수 (global 변수 )
pro_num = 10
global_data = {'subject': '김해준의 실용연기학원', 'day': 3, 'title': '안자는척 하기'}
def create_data(subject, day , title =None):
global pro_num
pro_num += 1
data = {'과목' : subject ,'일차' : day, '제목' : title, '문제 번호' : pro_num}
return data
result_1 = create_data('python',3)
print(result_1)
result_2 = create_data('web', 1, title = '몰래 많이먹기 액팅' )
print(result_2)
result_3 = create_data(**global_data)
print(result_3)
#{'과목': 'python', '일차': 3, '제목': None, '문제 번호': 11}
#{'과목': 'web', '일차': 1, '제목': '몰래 많이먹기 액팅', '문제 번호': 12}
#{'과목': '김해준의 실용연기학원', '일차': 3, '제목': '안자는척 하기', '문제 번호': 13}
global 변수 선언이 헷갈린다..
'SSAFY' 카테고리의 다른 글
[관통프로젝트 1주차] API 개념 (0) | 2024.07.19 |
---|---|
[수업기록] 모듈과 제어문의 모든 것 (1) | 2024.07.18 |
[수업기록] 파이썬 기초 문법(2) (4) | 2024.07.16 |
[수업복습] 슬라이싱 팬다. (1) | 2024.07.15 |
[수업기록] git clone, 프로그래밍 기초 및 파이썬 기초 문법(1) (0) | 2024.07.15 |