220530 Python -9 함수, lambda, map, filter
### 함수function
: 여러 개의 문장을 하나로 묶은 단위 --- 하나의 이름으로 묶어 호출해 사용하기 위함
: 반복적으로 호출해 실행 가능 --- 재사용성 + 프로그램을 논리적으로 구성할 수 있음
def 함수명(인수들):
문장
return 값
### 파이썬의 함수
1. 파이썬에서 함수는 def 키워드로 정의한다.
2. 함수는 위에서 정의를 하고, 아래에서 호출해야 한다. (인터프리터 언어 -> 순서가 바뀌면 오류 발생)
#매개변수 없는 함수
def hello(): #함수 정의. 정의만 했을 땐 정의한 내용이 실행되지 않음!
print('함수 호출 성공')
hello() #위에서 정의해둔 '함수 호출 성공' 이라는 문장이 출력됨
#매개변수 있는 함수
def abs(n): # n : 매개변수(parameter)
if n < 0:
n = -n
return n # return문 : 함수를 호출한 곳에 값을 돌려주는 역할
abs(-30)
print('돌려 받은값1:', abs(-30)) # 30
result = abs(50) --- (n>0이라 그대로 출력)
print('돌려 받은값2:', result) # 50
## 가변 매개변수(Arbitary Argument Variable)
1. 매개변수 앞에 * , **를 붙이면 가변 매개 변수가 된다.
2. 가변 매개변수는 입력 갯수가 달라져도 모두 받을 수 있다.
3. * 가 붙은 가변 매개변수는 입력받은 값들을 튜플(tuple)로 처리한다.
4. **가 붙은 가변 매개변수는 입력받은 값들을 딕셔너리(dict)로 처리한다.
# 일반 매개변수와 가변 매개변수를 같이 사용하는 함수
1. 일반 매개변수를 먼저 사용하고, 가변 매개변수는 가장 마지막에 사용해야 한다.
---> 가변 매개변수는 제한 없이 값을 받기 때문에 뒤에 붙는 일반 매개변수에 들어가는 값이 없게됨 = 오류
2. 일반 매개변수가 마지막에 놓일 경우 키워드 매개변수로 호출해야 한다.
def print_args(*args, n):
for i in range(n):
print(args[i], end='')
print()
# 함수 호출
print_args('파이썬', 1) # 오류 발생
print_args('파이썬', n=1) # 일반 매개변수 n=1임을 명시해 키워드 매개변수로 호출
## 지역 변수와 전역변수
1. 함수 안에서 정의된 변수는 함수 안에서만 사용 가능한 지역변수가 된다.
2. 함수 안에서 정의된 변수도 global 키워드를 붙이면 전역 변수가 된다.
3. 지역변수
1) 조건문, 반복문 안에서 정의된 변수
2) 함수 안에서 정의된 변수
3) 함수의 매개변수
a = 1 # 전역 변수
def vartest(a): # a : 매개변수, 지역변수
a = a + 1
print(a) # 2
print(a) # 1 (함수 내부의 값은 무효화됨)
------------------------------------
def scope():
global b # 전역 변수
b = 1
print('b1=', b) # b1 = 1
b = 10
scope() # 함수 호출 (전역변수 b 값을 초기화하는 함수)
print('b2=', b) # b2 = 1 (scope()함수에서 b=1이 되므로)
## pass : 함수나 클래스의 구현을 잠시 미루는 경우에 사용
(선언만 미리 해놓고 나중에 내용을 정의할 때!)
# 함수의 구현을 미루는 경우
def test():
pass
# 클래스 구현을 미루는 경우
class myclass:
pass
## 재귀함수(Recursive Function)
: 함수 안에서 자기자신의 함수를 호출하는 함수
# 팩토리얼을 구하는 재귀함수
def fact(n):
if n == 0:
return 1
else:
return n * fact(n-1)
------> 팩토리얼은 재귀함수보다 factorial() 함수를 사용함
import math
print('3!=', math.factorial(3))
print('5!=', math.factorial(5))
print('100!=', math.factorial(100))
## 중첩함수(Nested Function)
: 함수 안에 정의된 함수
import math
def stddev(*n): # 표준편차
def mean(): # 평균 : 중첩함수
return sum(n) / len(n)
def variance(m): # 분산 : 중첩함수
total = 0
for i in n:
total += (i-m)**2
return total / (len(n)-1)
v = variance(mean())
print('분산(v):', v) # 분산(v): 0.35999999999999993
return math.sqrt(v)
print('표준편차', stddev(2.3, 1.7, 1.4, 0.7, 1.9)) # 표준편차 0.6
## 함수를 변수에 담아서 사용하기
#1. 함수명을 변수에 담아서 사용하기
def something(a):
print(a)
p = something # 함수 이름을 변수 p에 저장
p(123) # 변수 p를 이용해서 something() 함수 호출
p('abc') # 변수 p를 이용해서 something() 함수 호출
#2. 함수명을 리스트에 담아서 사용하기
def plus(a,b):
return a+b
def minus(a,b):
return a-b
first = [plus, minus] # plus()함수와 minus()함수를 리스트에 저장
print(first[0](1,2)) # first[0]은 plus()함수를 의미함 ---- 3 출력
print(first[1](1,2)) # first[1]은 minus()함수를 의미함 ---- -1 출력
#3. 함수명을 매개변수로 전달해서 사용하기
def hello_korean():
print('안녕하세요')
def hello_english():
print('Hello')
def greet(hello): # 함수명을 매개변수로 전달
hello() # 함수 호출
greet(hello_korean) # greet() 함수 호출 ---- 안녕하세요 출력
greet(hello_english) # greet() 함수 호출 ---- Hello 출력
## lambda : 이름이 없는 한줄짜리 함수 (def로 정의하지 않는 함수)
: 일반적인 함수를 사용하기 힘든 경우나 좀더 간결하게 표현하고자 할때 사용함
# 형식 : lambda 인자1, 인자2,.... : 실행코드(리턴값)
1. (함수명을 변수에 담아서 사용하기)
add = lambda x, y : x+y # 람수(함수)를 add변수에 저장함
result = add(1, 3)
print('result:', result) # result: 4
2. (함수명을 리스트에 담아서 사용하기)
funcs = [ lambda x : x+'.pptx', lambda x : x+'.docx']
result1 = funcs[0]('Intro')
result2 = funcs[1]('Report')
print('result1:', result1) # result1: Intro.pptx
print('result2:', result2) # result2: Report.docx
3.★ (함수명을 매개변수로 전달해서 사용하기)
# { 'key ' : 'value' } = { '아기이름' : 출생아수 }
names = {'Mary':10999, 'Sams':2111, 'Aimy':9778, 'Tom':20245 , 'Michale':27115, 'Bob':5887, 'Kelly':7855}
※ names.items()가 lambda의 x로 들어가고 거기서 x[0] -> key, x[1] -> value 를 key로 정렬!
1. 아기이름(key)을 기준으로 오름차순 정렬
print(sorted(names.items(), key= lambda x : x[0])) #x[0]=key를 기준으로 오름차순 정렬
# [('Aimy', 9778), ('Bob', 5887), ('Kelly', 7855), ('Mary', 10999),
2. 아기이름(key)을 기준으로 내림차순 정렬
print(sorted(names.items(), key= lambda x : x[0], reverse=True)) #x[0]=key를 기준으로 내림차순 정렬
# [('Tom', 20245), ('Sams', 2111), ('Michale', 27115), ('Mary', 10999),
3. 출생아수(value)을 기준으로 오름차순 정렬
print(sorted(names.items(), key= lambda x : x[1])) #x[1]=value를 기준으로 오름차순 정렬
# [('Sams', 2111), ('Bob', 5887), ('Kelly', 7855), ('Aimy', 9778),
4. 출생아수(value)을 기준으로 내림차순 정렬
print(sorted(names.items(), key= lambda x : x[1], reverse=True)) #x[1]=value를 기준으로 내림차순 정렬
# [('Michale', 27115), ('Tom', 20245), ('Mary', 10999), ('Aimy', 9778)
원래
def f1(x):
return x[0]
이렇게 정의해서 key=f1 으로 불러오던 걸 key= lambda x : x[0] 로 간소화시킴!!
## map() 내장함수
: 인자를 바꾸어가며 함수를 반복 호출하여 결과를 return 받는 함수
def f(x):
return x*x
li = [1, 2, 3, 4, 5]
1. 반복문을 이용한 실행
for i in li:
print(f(i), end='\t')
print()
# 1 4 9 16 25
2. map() 함수를 이용한 실행
result = list(map(f, li)) # li의 원소값을 함수 f에 전달해 그 리턴값을 list로 만들어 result에 저장!
print('result:', result)
result: [1, 4, 9, 16, 25]
3. map() 함수와 lambda를 이용한 실행
result2 = list(map(lambda x : x*x, li)) # 함수 f 대신 lambda x:x*x 로 대체한 것!)
print('result2:', result2)
result2: [1, 4, 9, 16, 25]
## filter() 내장 함수
: 컬렉션과 lambda함수를 매개변수로 받아서 컬렉션의 모든 데이터를 lambda 함수의 매개변수로 대입해서 결과가 참인 경우에만 리턴하는 함수
li = [1, 2, 3, 4, 5]
print('lambda와 filter() 함수를 이용한 실행')
result = list(filter(lambda x : x%2==0, li)) # 짝수만 리턴
print('result:', result) # result: [2, 4]