3 - Python : function

최민규·2023년 1월 4일
0

함수

  • 반복적으로 사용되는 코드를 묶어서 사용하는 방법 → 코드의 유지 보수가 쉬워짐
  • def return argument parameter docstring scope lambda
  • 사용법 : 함수 선언(코드 작성) → 함수 호출(코드 실행)

로또 번호 출력

# 로또번호 출력(list)
# - 1 ~ 45의 랜덤한 숫자 6개 출력
# - 숫자 6개가 중복데이터가 없어야 함
# list 선언, random.randint(), while, break, if, not in, >=, len(), list.append()
# list.append() 리스트 데이터에 데이터를 추가
data = [1, 2, 3]
data.append(4)
data
import random

# 1. 로또번호 저장 변수 생성
lotto = []

# 2. 아래의 코드 반복 : while
while True:

#   2-1. 1 ~ 45 랜덤한 숫자 출력 후 저장 : random_number : random.randint()
    random_number = random.randint(1, 45)

#   2-2. lotto 리스트에 random_number 없으면, random_number를 lotto 변수에 추가 : list.append()
    # if random_number not in lotto:
    #     lotto.append(random_number)

#   2-2. random_number를 lotto 변수에 추가 : list.append()
    lotto.append(random_number)
    lotto = list(set(lotto))

#   2-3. lotto의 데이터 갯수가 6개 이상이면 반복 중단 : if, len(), break
    if len(lotto) >= 6:
        break

# 3. 로또번호 출력 : print()
lotto.sort()
print(lotto)
# 로또번호출력
lotto = []
while True:
    random_number = random.randint(1, 45)
    lotto.append(random_number)
    lotto = list(set(lotto))
    if len(lotto) >= 6:
        break
lotto.sort()
print(lotto)

# 파이썬출력
print('python')

# 로또번호출력
lotto = []
while True:
    random_number = random.randint(1, 45)
    lotto.append(random_number)
    lotto = list(set(lotto))
    if len(lotto) >= 6:
        break
lotto.sort()
print(lotto)

# Terminal
[7, 16, 20, 32, 34, 37]
python
[5, 9, 17, 29, 40, 42]

함수를 이용해서 로또 번호를 출력해보자

# 함수선언(코드작성)
def display_lotto():
    lotto = []
    while True:
        random_number = random.randint(1, 45)
        lotto.append(random_number)
        lotto = list(set(lotto))
        if len(lotto) >= 6:
            break
    lotto.sort()
    print(lotto)

# 함수호출(코드실행)
display_lotto()

# Terminal
[5, 24, 32, 40, 42, 44]
# 함수선언
def display_lotto():
    lotto = []
    while True:
        random_number = random.randint(1, 45)
        lotto.append(random_number)
        lotto = list(set(lotto))
        if len(lotto) >= 6:
            break
    lotto.sort()
    print(lotto)

# 로또번호출력
display_lotto()

# 파이썬출력
print('python')

# 로또번호출력
display_lotto()

# Terminal
[13, 14, 21, 34, 42, 45]
python
[13, 15, 19, 26, 35, 36]

argumentparameter

함수를 호출하는 코드에서 함수를 선언하는 코드로 데이터 전달할 때 사용

import random

# 함수선언
def display_lotto(count): # count : parameter
    lotto = []
    while True:
        random_number = random.randint(1, 45)
        lotto.append(random_number)
        lotto = list(set(lotto))
        if len(lotto) >= count:
            break
    lotto.sort()
    print(lotto)

# 로또번호출력 : 6개
display_lotto(6) # 6 : argument

# 로또번호출력 : 7개
display_lotto(7)

# Terminal
[1, 10, 16, 18, 25, 34]
[4, 6, 26, 27, 28, 32, 41]
# 함수선언(코드작성)
def plus(n1, n2=10, n3=20): # n1 : parameter, n2=10, n3=20 : default parameter
    print(n1 + n2 + n3)

# 함수호출(코드실행)
plus(1, n3=100) # 1 : argument, n3=100 : keyword argumnet

# Terminal
111
# 숫자의 범위와 숫자의 갯수를 아규먼트로 설정해서 함수를 호출할수 있도록 함수를 수정
# display_lotto를 호출할때 파라미터가 없으면 1 ~ 45까지 6개의 숫자를 출력
def display_lotto(count=6, end=45): # count : parameter
    lotto = []
    while True:
        random_number = random.randint(1, end)
        lotto.append(random_number)
        lotto = list(set(lotto))
        if len(lotto) >= count:
            break
    lotto.sort()
    print(lotto)

display_lotto() # 1 ~ 45까지 6개의 숫자
display_lotto(end=50, count=10) # 1 ~ 50까지 10개의 숫자
display_lotto(10, 50)

# Terminal
[2, 3, 15, 31, 36, 39]
[2, 8, 11, 16, 24, 26, 44, 45, 47, 50]
[4, 6, 7, 24, 26, 29, 33, 35, 36, 43]

return

  • 함수를 호출해서 결과 데이터를 변수에 저장할 때
  • 함수의 코드를 중단할 때
def plus1(n1, n2):
    print(n1 + n2)

def plus2(n1, n2):
    return n1 + n2
result1 = plus1(1, 2)
result2 = plus2(2, 3)
print(result1, result2)

# Terminal
3
None 5

리턴이 있는 함수 예시 : str.upper()

data = 'python'
result = data.upper()
print(data, result)

# Terminal
python PYTHON

리턴이 없는 함수 예시 : list.sort()

data = [1, 3, 2]
result = data.sort()
print(data, result)

# Terminal
[1, 2, 3] None

함수의 코드 실행 중단

def echo(msg, count=2):
    for idx in range(count): # [0, 1, 2, 3, 4, 5, 6]
        if idx >= 3:
            return
        print(msg)
    print('Done')
echo('python', 7)

# Terminal
python
python
python

여러개의 데이터를 리턴 1

def calc(n1, n2):
    result = [n1 + n2, n1 - n2]
    return result

result = calc(3, 1)
plus = result[0]
minus = result[1]
plus, minus

# Terminal
(4, 2)

여러개의 데이터를 리턴 2

def calc(n1, n2):
    return n1 + n2, n1 - n2

plus, _ = calc(3, 1)
plus

# Terminal
4

docstring

  • 함수의 설명을 작성 : 함수 선언 코드 바로 아래에 멀티라인 문자열로 작성
  • help() 함수로 해당 기능의 설명 출력 가능
def plus(n1, n2):
    '''
    This function is to plus two numbers.

    parameters
    ----------
    n1 : int, float : first number
    n2 : int, float : second number

    return
    ------
    n1 + n2 : int, float
    '''
    return n1 + n2
help(plus)

# Terminal
Help on function plus in module __main__:

plus(n1, n2)
    This function is to plus two numbers.
    
    parameters
    ----------
    n1 : int, float : first number
    n2 : int, float : second number
    
    return
    ------
    n1 + n2 : int, float
help(print)

# Terminal
Help on built-in function print in module builtins:

print(...)
    print(value, ..., sep=' ', end='\n', file=sys.stdout, flush=False)
    
    Prints the values to a stream, or to sys.stdout by default.
    Optional keyword arguments:
    file:  a file-like object (stream); defaults to the current sys.stdout.
    sep:   string inserted between values, default a space.
    end:   string appended after the last value, default a newline.
    flush: whether to forcibly flush the stream.
# 위의 help(print)에 출력된 print()의 설명을 통해 print되는 출력 결과물 변형하기

print('A', 'B', sep=', ', end='\t')
print('C', 'D')

# Terminal
A, B	C D

*args**kwargs

  • argument 의 갯수에 상관없이 함수를 실행하는 방법
  • *args : 여러 개의 키워드가 없는 아규먼트를 튜플 데이터 타입으로 받아줌
  • **kwargs : 여러 개의 키워드 아규먼트를 딕셔너리 데이터 타입으로 받아줌
def plus(*args, **kwargs): # 파라미터에 컬렉션 데이터 타입을 받아줌 : 식별자1개, 데이터n개
    print(type(args), args)
    print(type(kwargs), kwargs)
    return sum(args) + sum(kwargs.values())

# 키워드 아규먼트는 키워드가 없는 아규먼트 뒤에 사용
# 디폴트 파라미터는 디폴트 값이 없는 파라미터 뒤에 사용
plus(1, 2, 3, 4, 5, n1=10, n2=30) # 여러개의 아규먼트

# Terminal
<class 'tuple'> (1, 2, 3, 4, 5)
<class 'dict'> {'n1': 10, 'n2': 30}
55
data = {'num1': 10, 'num2': 20}
data.keys(), data.values()

# Terminal
(dict_keys(['num1', 'num2']), dict_values([10, 20]))

*args **kwargs

  • parameter
    • 여러 개의 argument → 하나의 컬렉션 데이터 타입(tuple dict)으로 묶어서 받아줌
    • *args : 키워드가 없는 여러 개의 argument 를 받음 (tuple)
    • **kwargs : 키워드가 있는 여러 개의 argument 를 받음 (dict)
  • argument
    • 묶여있는 컬렉션 데이터 타입(list tuple dict) → 여러 개의 argument 로 풀어서 함수 호출
    • *args : list tuple 데이터 타입의 데이터를 여러 개의 키워드가 없는 argument 로 풀어줌
    • **kwargs : dict 데이터 타입의 데이터를 여러 개의 키워드가 있는 argument 로 풀어줌
def echo(*args, **kwargs):
    print(type(args), args)
    print(type(kwargs), kwargs)
data = [1, 2, 3]
echo(data)  # echo([1, 2, 3]) > 아규먼트 : 1개, 데이터타입 : 리스트
echo(*data) # echo(1, 2, 3) > 아규먼트 : 3개, 데이터타입 : 정수

# Terminal
<class 'tuple'> ([1, 2, 3],)
<class 'dict'> {}
<class 'tuple'> (1, 2, 3)
<class 'dict'> {}
data = {'num1': 10, 'num2': 20}
echo(data)   # echo({'num1': 10, 'num2': 20}) > 아규먼트 1개, 데이터타입 : 딕셔너리
echo(**data) # echo(num1=10, num2=20) > 키워드 아규먼트 2개, 데이터타입 : 정수

# Terminal
<class 'tuple'> ({'num1': 10, 'num2': 20},)
<class 'dict'> {}
<class 'tuple'> ()
<class 'dict'> {'num1': 10, 'num2': 20}

데이터베이스 접속 함수

def connect(**kwargs):
    print('connect :', kwargs['host'], kwargs['user'], kwargs['pw'])
# 1
connect(host='1.2.3.5', user='python', pw='1234')
connect(host='1.2.3.5', user='python', pw='1234')
# 2
data = {'host': '1.2.3.6', 'user': 'python', 'pw': '1234'}
connect(host=data['host'], user=data['user'], pw=data['pw'])
connect(host=data['host'], user=data['user'], pw=data['pw'])

# Terminal
connect : 1.2.3.6 python 1234
connect : 1.2.3.6 python 1234
# 3
data = {'host': '1.2.3.6', 'user': 'python', 'pw': '1234'}
# connect(host=data['host'], user=data['user'], pw=data['pw'])
connect(**data)
connect(**data)

# Terminal
connect : 1.2.3.6 python 1234
connect : 1.2.3.6 python 1234

→ 위의 세 가지 방식으로 함수를 입력할 수 있지만 3번이 가장 경제적인 방식이다


Scope

  • 함수 밖 : 전역영역 global
  • 함수 안 : 지역영역 local

실수할 만한 코드 3

data = 10

def change():
    data = 20

change()
print(data)

# Terminal
10

# 맨 윗줄의 data가 함수의 영향을 받아 ‘20’이 나올 것을 기대했지만 ‘10’이 출력되었다 왜 그럴까
# global : 지역영역에서 전역영역의 변수사용 방법
data = 10

def change():
    global data
    data = 20

change()
print(data)

# Terminal
20

# 맨 위의 data는 함수 밖에서 선언된 `global` 이고 
# 함수 내에서 선언된 data는 `local` 로 서로 다르기 때문이다

# 함수 안에서 `global` 을 지정해주면 함수의 적용을 받아 ‘20’이 출력된다
# 지역영역에서 사용되는 변수(식별자)는 지역영역 없으면, 전역영역의 변수를 가져와서 사용
data = 10

def change():
    print('local', data)

change()
print('global', data)

# Terminal
local 10
global 10
# return : 전역영역에서 지역영역의 변수 사용하는 방법
data = 10

def change():
    data = 20
    return data

data = change()
print(data)

# Terminal
20
data = 10

def change1():
    data = 20
    def change2():
        global data
        print('local', data)
    change2()

change1()

# Terminal
local 10

lambda

  • 일회성 함수로 간단한 함수(parameter return)를 함수 선언 없이 사용 가능
  • 메모리 절약, 가독성 증대
func = lambda n1, n2: n1 + n2
func(1, 2)

# Terminal
3
# 저장공간 1칸 사용
def calc(func, n1, n2):
    return func(n1, n2)
calc(lambda n1, n2: n1 + n2, 1, 2), calc(lambda n1, n2: n1 - n2, 1, 2)

# Terminal
(3, -1)

list comprehension

  • 간단한 반복문, 조건문을 사용해서 리스트 데이터를 만들 때 사용하는 문법
  • 주로 리스트 데이터를 필터링하거나 데이터를 변경할 때 사용
# 0 ~ 9 까지의 데이터에서 홀수만 뽑아서 제곱한 결과를 리스트로 출력
# 일반적인 반복, 조건문 작성 방식

result = []
for number in range(10):
    if number % 2:
        result.append(number ** 2)
result

# Terminal
[1, 9, 25, 49, 81]
# list comprehension 작성 방식

result = [number ** 2 for number in range(10) if number % 2]
result

# Terminal
[1, 9, 25, 49, 81]
# 2020년도 보고서 목록을 리스트로 출력
reports = ['사업보고서(2020)', '감사보고서(2021)', '[기재정정]사업보고서(2020)']

reports_2020 = [report[:-6] for report in reports if report[-5:-1] == '2020']
reports_2020

# Terminal
['사업보고서', '[기재정정]사업보고서']
reports_2020 = {report[:-6]: report[-5:-1] for report in reports if report[-5:-1] == '2020'}
reports_2020

# Terminal
{'사업보고서': '2020', '[기재정정]사업보고서': '2020'}
# kim씨 성을 가진 이름을 연령대로 데이터를 바꿔서 리스트로 출력
names = ['kim python(23)', 'lee notebook(32)', 'kim macbook(47)']
def ages(data):
    return data[:-3] + str(int(data[-3:-1]) // 10 * 10) + ')'

names_kim = [
    ages(name)
    for name in names 
    if name.split(' ')[0] == 'kim'
]

names_kim

# Terminal
['kim python(20)', 'kim macbook(40)']
name = 'kim python'
name.split(' ')[0]

# Terminal
'kim'

map()

  • iterable한 데이터의 모든 value에 특정 함수를 적용한 결과를 리스트로 출력
names = ['kim python(23)', 'lee notebook(32)', 'kim macbook(47)']

def ages(data):
    return data[:-3] + str(int(data[-3:-1]) // 10 * 10) + ')'

list(map(ages, names))

# Terminal
['kim python(20)', 'lee notebook(30)', 'kim macbook(40)']
names1 = ['kim python(23)', 'lee notebook(32)', 'kim macbook(47)']
names2 = ['kim py(33)', 'lee note(52)', 'kim book(87)']

def ages(*args):
    return [data[:-3] + str(int(data[-3:-1]) // 10 * 10) + ')' for data in args]

print(list(map(ages, names1, names2)))

# Terminal
[['kim python(20)', 'kim py(30)'], ['lee notebook(30)', 'lee note(50)'], ['kim macbook(40)', 'kim book(80)']]
profile
안녕

0개의 댓글