python function

함수

  • 반복되는 코드를 묶음으로 효율적인 코드를 작성하도록 해주는 기능
  • 기본 함수
  • 파라미터와 아규먼트
  • 리턴
  • args, *kwargs
  • docstring
  • scope
  • inner function
  • lambda function
  • Map, Filter, Reduce
  • Decorlator

1. 기본 함수

  • 함수의 선언과 호출
    1
    2
    3
    4
    5
    6
    7
    8
    # 함수선언
    def grade(point): # def : 예약어, 함수이름 : grade, 파라미터 : point
    if point >= 90:
    print("A")
    elif point >= 80:
    print("B")
    else:
    print("C")
    1
    2
    # 함수호출
    grade(88) # 함수이름(point로 넘겨줄 값을 입력)

2. 파라미터와 아규먼트

  • 파라미터: 함수를 선언할 때 호출하는 부분에서 보내주는 데이터를 받는 변수
  • 아규먼트: 함수를 호출할 때 함수에 보내주는 데이터
1
2
3
def plus(num1, num2): # 파라미터
print(num1 + num2)
plus(1, 2) # 아규먼트
1
2
3
def plus(num1, num2=10): # 디폴트 파라미터
print(num1 + num2)
plus(1, 2) # 아규먼트
1
2
3
def plus(num1, num2=10, num3=20): # 디폴트 파라미터
print(num1 + num2 - num3)
plus(1, 2) # 아규먼트
  • 키워드 아규먼트 : 특정 파라미터를 지정해서 넣고 싶을 때 사용
    1
    plus(3, num3=100) # 키워드 아규먼트

3. 리턴

  • 함수를 실행한 결과를 저장하고 싶을 때 사용합니다.
  • 함수에서 return 코드가 실행되면 무조건 함수가 종료됩니다.
  • return
    1
    2
    3
    4
    5
    def plus(num1, num2):
    print(num1 + num2)

    result = plus(1, 2)
    print(result)
    1
    2
    3
    4
    5
    6
    def plus(num1, num2):
    print(num1 + num2)
    return num1 + num2

    result = plus(1, 2)
    print(result)
    1
    2
    3
    4
    5
    6
    7
    8
    9
    def grade(point): # def : 예약어, 함수이름 : grade, 파라미터 : point
    if point >= 90:
    return "A"
    elif point >= 80:
    return "B"
    else:
    return "C"

    grade(90)
    1
    2
    3
    4
    5
    6
    7
    def passornot(result):
    pass_ = ""
    if result == "A" or result == "B":
    return "PASS"
    else:
    return "FAIL"
    passornot("A")
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    def grade(point): # def : 예약어, 함수이름 : grade, 파라미터 : point
    if point >= 90:
    return "A"
    elif point >= 80:
    return "B"
    else:
    return "C"

    def passornot(result):
    pass_ = ""
    if result == "A" or result == "B":
    return "PASS"
    else:
    return "FAIL"
    1
    2
    # 함수 호출하기
    passornot(grade(98))
    1
    2
    3
    4
    5
    # 함수에서 return 코드가 실행되면 무조건 함수가 종료됩니다. 
    def echo(msg):
    if msg == 'quit':
    return
    print(msg)

4. args, *kwargs

  • 함수를 호출할 때 아규먼트와 키워드 아규먼트의 갯수를 특정지을 수 없을 때 사용
    1
    2
    3
    4
    5
    6
    7
    # 갯수에 상관없이 모든 아규먼트를 더해주는  함수
    def plus(*args):
    print(type(args), args)
    return sum(args)

    # 함수 호출
    plus(1, 2, 3, 4, 5)
    1
    2
    3
    4
    5
    6
    7
    8
    # 키워드가 있는 아규먼트
    def plus(*args, **kwargs):
    print(type(args), args)
    print(type(kwargs), kwargs)
    return sum(args) + sum(kwargs.values())

    # 함수 실행
    plus(1, 2, 3, 4, 5, num1=6, num2=7)
    1
    2
    3
    4
    5
    def func(num1, num2, num3):
    return num1 + num2 + num3

    data = [1, 2, 3]
    func(*data) # func(1, 2, 3)
    1
    2
    3
    4
    5
    def func(num1, num2=10, num3=20):
    return sum(num1) + num2 + num3

    data = [1, 2, 3]
    func(data) # func([1, 2, 3])
    1
    2
    3
    4
    5
    def func(num1, num2, num3):
    return num1 + num2 + num3

    data = [1, 2, 3]
    func(*data) # func(1, 2, 3)
    1
    2
    3
    4
    5
    6
    7
    def func(num1, num2, num3):
    return num1 + num2 + num3
    data = {
    "num2": 100,
    "num3": 200,
    }
    func(1, **data) # func(1, num2=100, num3=200)
  • 문장을 입력받아서 문법에 맞도록 결과를 출력하는 코드를 작성
  • 마지막 문자는 . 이 있을수도 있고 없을수도 있습니다.
  • 논리적인 문제해결 순서 -> 코드로 변경
  • str.upper(), str.lower(), offset index [], str.add(문자열 덧셈)
  • python IS the best Language
  • python IS the best Language.
  • Python is the best lagnuage.
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    # 1. 문자열 입력받기
    sentence = input('input sentence : ')

    # 2. 모두 소문자로 변경
    result = sentence.lower() # lower함수는 리턴이 있는 함수이므로 result에 저장

    # 3. 가장 앞글자를 대문자로 변경
    result = result[0].upper() + result[1:] # 가장 앞글자 + 나머지 글자

    # 4. 마지막 문자가 .인지 확인해서 .이 아니면 .을 추가
    if result[-1] != ".":
    result += "."

    result
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    # 6자리의 로또번호를 생성하는 코드를 작성하세요. 
    # 6자리의 번호는 중복이 없어야 합니다.
    # 문자열, 숫자, 리스트
    # while, not in, in, list.append(), break, len(), list.sort()
    # 문제가 조금 복잡하면 간단한 기능부터 구현하고 업데이트를 하는 방법으로 해결
    # 랜덤한 숫자 6개 출력 -> 숫자가 중복되지 않는 코드를 추가

    lotto = []
    # 랜덤한 숫자 6개를 while문을 사용해서 작성
    while True:
    num = random.randint(1, 45)
    # 숫자를 추가할 때 lotto 리스트에 중복되는 숫자가 없으면 추가
    if num not in lotto:
    lotto.append(num)
    if len(lotto) >= 6:
    lotto.sort()

    break
    lotto

5. docstring

1
2
3
4
# 한줄로 작성
def echo(msg):
"echo print msg"
print(msg)
1
2
3
4
5
6
7
8
9
10
11
def echo(msg):
"""
echo func return its input agument
The operation is:
1. print msg parameter
2. return msg parameter
param : mag : str
return : str
"""
print(msg)
return msg
1
2
# docstring 확인 방법
echo?
1
echo??
1
help(echo)
1
print(echo.__doc__)

6. Scope 범위

  • 함수 안에서 선언되는 변수와 함수 밖에서 선언되는 변수의 범위가 다릅니다.
  • global(전역), local(지역)
  • 전역영역에 선언되어있으면 함수가 실행될 때 전역영역의 변수를 가져다 사용합니다.
  • 지역영역에 선언되어있으면 함수가 실행될 때 지역영역의 변수를 가져다 사용합니다.
  • 메모리를 덜 잡아먹기 때문에 로컬영역에서 선언할 수 있으면 로컬에서 선언하는 것이 좋습니다.
1
2
3
4
5
6
7
# global
gv = 10

def echo():
print(gv)

echo()
1
2
3
4
5
6
7
8
9
# local
gv = 10

def echo():
gv = 100
print(gv)

echo() # 100
gv # 10
1
2
3
4
5
6
7
8
9
gv = 10 

def echo():
global gv
gv=100
print(gv)

echo()
gv # 100

7. inner function

  • 함수가 지역영역에 선언, 함수 안에 함수가 선언
    1
    2
    3
    4
    5
    6
    def outer(a, b):

    def inner(c, d):
    return c + d

    return inner(a, b)
    1
    outer(1, 2) # 3
    1
    inner(2, 3) # 오류발생 : 전역영역에서 지역영역의 함수를 사용하려 했기 때문입니다. 지역영역에 선언된 함수이므로 지역영역에서만 사용할 수 있습니다.

inner함수 = 익명함수라고 부릅니다. 전역영역에서 가져다 사용할 수 없는 함수이기 때문입니다.

1
2
3
4
5
6
7
8
9
10
# 지역영역의 함수 사용하기
def outer(a, b):

def inner(c, d):
print(a, b)
return c + d

return inner # 리턴을 변경시켜주고

outer(1, 2)(3, 4) # inner(3, 4)

8. callback function

  • 함수를 아규먼트, 파라미터로 설정해서 사용하는 것을 의미합니다.
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    def calc(func, a, b):
    # code
    a **= 2
    b **= 2
    return func(a, b)

    def plus(a, b):
    return a + b

    def minus(a, b):
    return a - b
    1
    2
    # 덧셈
    calc(plus, 1, 2)
    1
    2
    # 뺄셈
    calc(minus, 1, 2)

9. lambda function

  • 파라미터를 간단한 계산으로 리턴되는 함수 : 삼항연산
    1
    2
    3
    4
    5
    def plus(a, b): # 파라미터
    return a + b # 리턴

    # lambda 파라미터: 리턴
    plus2 = lambda a, b: a + b
    1
    plus2(2, 3)
    1
    calc(lambda a, b: a + b, 4, 5)

10. Map, Filter, Reduce

  • map: 순서가 있는 데이터 집합에서 모든 값에 함수를 적용시킨 결과를 출력
  • 아규먼트로 func(함수), *iterable을 받음
  • iterable 한 데이터에 함수를 각 요소마다 모두 적용시킨 결과 데이터를 만들고 싶을 때 사용합니다.
  • map(func, ls1, ls2) : ls(iterable한 데이터)가 여러개 올 수 있습니다.
1
2
3
4
5
6
ls = [1, 2, 3, 4]

def odd_even(num):
return 'odd' if num % 2 else 'even'

odd_even(3), odd_even(4)
1
list(map(odd_even, ls)) # 함수, 리스트를 넣음
1
2
3
4
5
6
7
8
9
10
# input 함수로 구분자는 " "으로 여러개의 숫자를 입력 받습니다. 
# str.split(" ")리스트로 만들고
# 만들어진 리스트의 값들을 int로 형변환
datas = input("insert numbers : ") # 10 20 30 40 50 40 30 20 10
result = datas.split(" ")
result
```
```python
result = list(map(int, result))
result

10-2. Filter

  • Filter : 리스트 데이터에서 특정 조건에 맞는 value만 남기는 함수
  • filter(func, ls) : ls(iterable한 데이터)가 1개밖에 못옵니다.
  • True, False로 만듭니다.
  • func is True인 것만 리턴합니다.
    1
    2
    3
    4
    ls = range(10)

    # 홀수만 출력
    list(filter(lambda data: True if data % 2 else False, ls))

10-3. Reduce

  • 리스트 데이터를 처음부터 순서대로 특정 함수를 실행하여 결과를 누적시켜 주는 함수
    1
    2
    3
    4
    5
    6
    from functools import reduce # import 해야 사용 가능합니다. 

    ls = [3, 1, 2, 4, 5]
    # ((((1+2)+3)+4)+5)
    # 파라미터가 반드시 2개여야 함
    reduce(lambda x, y: x + y, ls)

10. Decorlator

  • 함수에서 코드를 바꾸지 않고 기능을 추가하거나 수정하고 싶을 때 사용하는 문법
    1
    2
    3
    4
    5
    6
    7
    8
    9
    def a():
    code_1
    code_2
    code_3

    def b():
    code_1
    code_4
    code_3

데코레이터의 사용

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
def c(func): # 2. func으로 def a()이 들어옴 

def wrapper(*args, **kwargs): # inner func
code_1 # 4. 코드가 실행됨
result = func(*args, **kwargs) # 5. 코드가 실행됨
code_3 # 6. 코드가 실행됨
return result # 7. 반환함

return wrapper # 8. 반환함

@c # 1. def c라는 함수가 실행이 됨, code_1, code_3 기능이 적용됨, code_1, 3, 2가 실행됨
def a(): # def a라는 함수가 wrapper 함수로 변경됨
code_2 # 3. code_2 가 실행됨

@c # code_1, code_3 기능이 실행됨, 결과적으로 code_1, 3, 4가 실행됨
def b(): # b라는 함수가 wrapper 함수로 변경됨
code_4
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# a
def plus(a, b):
print("start") # code_1
result = a + b # code_2
print("result : {}".format(result)) # code_3
return result

# b
def minus(a, b):
print("start") # code_1
result = a - b # code_4
print("result : {}".format(result)) # code_3
return result

# c : code_1, cod_3을 묶어주는 데코레이션 함수
def disp(func):
def wrapper(*args, **kwargs):
print("start") # code_1
result = func(*args, **kwargs) # code_2, code_4
print("result : {}".format(result)) # code_3
return result
return wrapper
1
2
3
4
5
@disp
def plus(a, b):
result = a + b # code_2
return result
plus(1, 2)
1
2
3
4
5
6
7
8
9
10
11
12
# 함수의 실행 시간을 출력하는 데코레이터 함수를 작성하세요. 
import time


def timer(func):
def wrapper(*args, **kwargs):
start_time = time.time() # code 1
result = func(*args, **kwargs) # code 2, code 4
end_time = time.time() # code 3
print("running time : {}".format(end_time - start_time)) # code 3
return result
return wrapper
1
2
3
4
@timer
def test1(num1, num2):
data = range(num1, num2+1)
return sum(data)
1
2
3
4
5
6
@timer
def test2(num1, num2):
result = 0
for num in range(num1, num2+1):
result += num
return result
1
test1(1, 100000)
1
test2(1, 100000)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 패스워드를 입력받아야 함수가 실행되도록하는 데코레이터 작성
def check_password(func):
def wrapper(*args, **kwargs):
pw = 'dss12'
# datas = [
# {'id': 'test', 'pw': '1234'},
# {'id': 'test2', 'pw': '12345'}
# ]
# check password
input_pw = input('insert pw : ')
if input_pw == pw:
result = func(*args, **kwargs)
else:
result = 'not allow!'
return result
return wrapper
1
2
3
@check_password
def plus(a, b):
return a + b
1
plus(1, 2)
1
2
3
4
5
6
7
8
9
10
11
@check_password
def lotto_func():
lotto = []
while True:
number = random.randint(1, 45)
if number not in lotto:
lotto.append(number)
if len(lotto) >= 6:
lotto.sort()
break
return lotto
1
lotto_func()

join()

  • 리스트로 되어있는 데이터를 특정 문자열을 구분자로 사용해서 하나의 문장으로 만들어주는 함수
    1
    2
    ls = ['python', 'is', 'good']
    " ".join(ls)
    1
    2
    3
    4
    5
    6
    7
    8
    # pandas dataframe
    import pandas as pd

    df = pd.DataFrame([ # DataFrame : class
    {"name": "jin", "age": 20},
    {"name": "andy", "age": 21},
    ])
    df

id, pw 카운트 함수, 1. zip함수를 이용하는 방법

1
2
3
4
5
ls = ['a', 'b', 'c']
print(list(range(len(ls))))
print(list(zip(range(len(ls)), ls)))
for idx, data in list(zip(range(len(ls)), ls)):
print(idx, data)
1
2
3
4
user_datas = [
{'user': 'test', 'pw': '1234', 'count': 0},
{'user': 'python', 'pw': '5678', 'count': 0},
]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# user_data를 입력받아서 아이디와 패스워드를 체크하는 데코레이터 함수를 코드로 작성하세요. 
# 로그인 될 때마다 count를 1씩 증가
def need_login(func):
def wrapper(*args, **kwargs): # inner function 만듬
# 아아디 패스워드 입력
user, pw = tuple(input("insert user pw : ").split(' ')) # user와 pw 나눈 후 tuple로 변환

# 존재하는 아이디와 패스워드 확인
for idx, user_data in zip(range(len(user_datas)), user_datas): # 카운트하기 위해 몇 번째 데이터인지 확인필요
if (user_data['user'] == user) and (user_data['pw'] == pw):
user_datas[idx]['count'] += 1 # 유저 데이터의 인덱스에서 카운트를 1씩 증가 시킴
# 함수 실행
return func(*args, **kwargs) # wrapper 함수 종료, 결과값 출력
return "wrong login data!"
return wrapper
1
2
3
4
5
@need_login
def plus(num1, num2):
return num1 + num2

plus(1, 2)
1
user_datas

2. enumerate함수를 이용하는 방법

1
list(enumerate(user_datas))
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# user_data를 입력받아서 아이디와 패스워드를 체크하는 데코레이터 함수를 코드로 작성하세요. 
# 로그인 될 때마다 count를 1씩 증가
def need_login(func):
def wrapper(*args, **kwargs): # inner function 만듬
# 아아디 패스워드 입력
user, pw = tuple(input("insert user pw : ").split(' ')) # user와 pw 나눈 후 tuple로 변환

# 존재하는 아이디와 패스워드 확인
for idx, user_data in enumerate(user_datas): # 카운트하기 위해 몇 번째 데이터인지 확인필요
if (user_data['user'] == user) and (user_data['pw'] == pw):
user_datas[idx]['count'] += 1 # 유저 데이터의 인덱스에서 카운트를 1씩 증가 시킴
# 함수 실행
return func(*args, **kwargs) # wrapper 함수 종료, 결과값 출력
return "wrong login data!"
return wrapper
1
2
3
4
5
@need_login
def plus(num1, num2):
return num1 + num2

plus(1, 2)
1
user_datas