본문 바로가기

Python/▶ Python

TIL ③일차

728x90
더보기

DAY 3 박두진 강사님 (Python 함수)

1.Lotto 번호 생성기

(1주차 때 했었던 방법과 또 다르다.. 이번방법이랑 전에 했던 방법 둘다 풀어보자)

① randint( )함수이용

#로또번호 출력
# 1~45의 랜덤한 숫자 6개 출력
# 숫자 6개 중복 x
---------------------------------------------------------------------------
import random
 
lotto = []

while True:
    random_number = random.randint(1,45)  # randint = 복원추출. 값중복 될수도 있음.
    lotto.append(random_number)
    if len(lotto) >= 6:
        break
lotto.sort()
print(lotto, "추첨이 종료되었습니다!")
-----------------------------------------------------------------------------
[19, 23, 24, 30, 30, 37] 추첨이 종료되었습니다!

※이렇게 만들면 중복 발생 . 중복 제거하기 위해 2가지 방법을 사용할 수 있다.

 

1) 집합 set( ) 사용

   -set으로 lotto 값을 감싸주어 중복 값 제거한 후에 다시 list로 변환 ( set에는 .append가 안되므로)

   -첫 줄에서 난수를 lotto 리스트에 추가. 두 번째 줄에서 lotto를 집합으로 변환시켜주어 중복된 값 있으면 필터링후 다시       리스트형태로 재정비. 계속 반복. 

lotto.append(random_number)
lotto = list(set(lotto))

2) 논리 함수 사용

   -if , not in 으로 난수가 lotto 리스트에 없는 것이 확인 되면 데이터로 추가.

if random_number not in lotto:
        lotto.append(random_number)

② sample.( ) 함수 이용

더보기

전에 한 번 풀어보긴했는데 이번에 다시 풀려니까 생각이 하나도 안나서..

이용하는 함수가 다르니까 다시 풀어보자.

현재 갖고 있는 돈에다가 도전횟수만큼 금액 차감되는 시스템도 추가해보았다.

몇번 오류나고 했지만..완성

이거하는데도 시간 꽤 많이썼네.. 갈 길이 멀다

import random

chance = int(input("몇 번 도전하시겠습니까?(횟수당 1000원): "))
now_money = 50000
now_money -= chance * 1000

for random_number in range(chance):
    random_number = random.sample(range(1, 46), 6)
    print(random_number)

print(f'현재 잔액은 {now_money}원입니다.추첨이 종료되었습니다.!')
--------------------------------------------------------------------------------
몇 번 도전하시겠습니까?(횟수당 1000원): 6
[2, 20, 10, 35, 21, 12]
[25, 12, 31, 9, 41, 40]
[35, 4, 26, 28, 42, 20]
[38, 15, 17, 11, 33, 32]
[38, 23, 14, 40, 29, 37]
[11, 25, 30, 45, 13, 3]
현재 잔액은 44000원입니다.추첨이 종료되었습니다.!
추첨이 종료되었습니다.!

 

2. function

# 반복적으로 사용되는 코드를 묶어서 사용하는 방법 > 코드의 유지보수가 쉬워짐.
# def, return, argument, parameter, docstring, scope, lambda
# 사용법 : 함수선언(코드작성) > 함수호출(코드실행)  -> 코드 누군가 작성해 놓으면 우리가 바로 가져다가 쓸 수 있음 
 
#로또번호출력, #파이썬출력, #로또번호출력 같은 반복작업을
더보기
# 로또번호출력
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)

 

def( )함수를 이용하면 

더보기
#함수선언(코드작성)
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()

 

이렇게 간단해진다

# 함수선언
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()

 

3. argument, parameter

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

1) keyword argument, default parameter

 
Lotto 생성 코드를 예로 들면,

#함수선언 시 def 함수명(count) 부분이  parameter 이며

#함수호출 시 함수명(숫자) 부분이 argument이다

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)

 

좀 더 간단하게 예를 들면,

n1, n2 : parameter

1, 2 : argument

#함수선언(코드작성)
def plus(n1, n2) : #n1, n2 :parameter
    print(n1 + n2)

#함수호출(코드실행)
plus(1,2) #1, 2 argument

 

2) keyword argument, default parameter

 

- parameter는 고정시켜줄 수 있음 -> argument에 data 없을 시 default parameter 대입

- #함수호출 시, n2 자리는 공석이므로 default parameter 대입

                         n3 자리는 별도로 입력해주었으므로 입력한 값 대입

# 함수선언(코드작성)
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
-------------------------------------------------------------------------------
111

 

 -기존 Lotto 생성기사용

          parameter                            randint함수의 끝숫자( 45 -> end )

                                                      카운트하는 숫자를 변수로 변경( 6 -> count )

          argument                             count 부분 ( end =50 )

                                                      카운트하는 숫자를 변수로 변경( count = 10 )

※end와 count 위치가 바뀌어도 상관없는 이유 : end와 count라는 식별자가 지정이 되어있기 때문에 자리는 크게 상관 X

# 숫자의 범위와 숫자의 갯수를 아규먼트로 설정해서 함수를 호출할수 있도록 함수를 수정
# display_lotto를 호출할때 파라미터가 없으면 1 ~ 45까지 6개의 숫자를 출력
def display_lotto(count=6, end=45): # count, end : 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개의 숫자

 

4. return

# return
# 함수를 호출해서 결과 데이터를 변수에 저장할 때
# 함수의 코드를 중단할 때
 
 

●함수 안에서 return 사용하면 값을 함수 바깥으로 반환함(return에 값 지정하지 않을 시 None 반환)

●return 사용 시 값을 함수 바깥으로 반환할 수 있고, 그 값을 변수에 저장 가능

●return으로 반환하는 값은 반환값이라고 하며, 함수를 호출해준 바깥에 결과를 알리기 위함

출처 :[파이썬 강의] UNIT 29.3 함수의 결과를 반환하기 - YouTube

 

 

몇 번 계산해보고 결과 값을 보다보니까

def ( ) 로 함수 정의 후 계산 시, 결과값은 출력이 되지만 별도의 공간을 차지하진 않는 것 같다.

그래서 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)
-------------------------------------------------------------
3
None 5

 

ex) 리턴이 있는 함수 예시 

# 리턴이 있는 함수 예시 : str.upper()
data = 'python'
result = data.upper()
print(data, result)
-------------------------------------
python PYTHON

 

ex) 리턴이 없는 함수 예시

-

# 리턴이 없는 함수 예시 : list.sort()
data = [1, 3, 2]
result = data.sort()
print(data, result)
-----------------------------------
[1, 2, 3] None

 

# 함수의 코드를 중단할 때

def echo(msg, count=3):
    for idx in range(count):
        if idx >= 5:
            return        #break 였으면 : Done 출력 --> break는 for문만 빠져나오므로
        print(msg)
    print('Done')
    
    echo('python', 8)
    ---------------------------------------------------------------------------------
    python
    python
    python
    python
    python

 

 

 

4. docstring

# docstring  --> 패키지마다, 사용하는 회사마다 docstring의 양식은 상이함.
# 함수의 설명을 작성 : 함수선언코드 바로 아래에 멀티라인 문자열로 작성
# help() 함수로 docstring 출력
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
#docstring 확인 방법 : help(plus) , Ctrl + Space bar
 

5. *args 와 **kwargs

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

#키워드가 있는 아규먼트는 키워드가 없는 아규먼트 뒤에 사용
#디폴트 파라미터는 디폴트 값이 없는 파라미터 뒤에 써주기!!!!!!!!!
plus(1, 2, 3, 4, 5, n1=10, n2=30) # 여러개의 아규먼트
--------------------------------------------------------------------------------------
<class 'tuple'> (1, 2, 3, 4, 5)
<class 'dict'> {'n1': 10, 'n2': 30}
 
 
# *args, **kwargs : 아규먼트에서 사용
# 파라미터 사용 : 여러개의 아규먼트 > 컬렉션 데이터타입(tuple,dict)으로 묶어줌
# 아규먼트 사용 : 컬렉션 데이터타입(list,tuple,dict) > 여러개의 아규먼트로 풀어줌
 
 
※ {}안이 빈 칸인 이유는 아규먼트 자리에 키워드를 가진 아규먼트가 없기 때문에 데이터 타입은 dic으로 받았지만 값은 공백인 것 같다.

 

※아규먼트에서 *data를 해주어서 리스트 타입이었던 data=[ ] 가 여러개 (정수 1, 2, 3) 으로 풀린 것 같다.
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개, 데이터 타입 : 정수
-----------------------------------------------------------------------
<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개, 데이터타입 : 정수
-------------------------------------------------------------------------------
<class 'tuple'> ({'num1': 10, 'num2': 20},)
<class 'dict'> {}
<class 'tuple'> ()
<class 'dict'> {'num1': 10, 'num2': 20}
*args, **kwargs
parameter
   - 여러개의 아규먼트 > 하나의 컬렉션 데이터타입(tuple,dict)으로 묶어서 받아줌
   - *args : 키워드가 없는 여러개의 아규먼트를 받음 : tuple
   - **kwargs : 키워드가 있는 여러개의 아규먼트를 받음 : dict
 argument
  - 묶여있는 컬렉션 데이터타입(list,tuple,dict) > 여러개의 아규먼트로 풀어서 함수호출
  - *args : list, tuple 데이터타입의 데이터를 여러개의 키워드가 없는 아규먼트로 풀어줌
 - **kwargs : dict 데이터타입의 데이터를 여러개의 키워드가 있는 아규먼트로 풀어줌

 

6. 데이터베이스 접속함수

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'])
-----------------------------------------------------------------
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)
-------------------------------------------------------------------
connect :  1.2.3.6 python 1234
connect :  1.2.3.6 python 1234

3번이 가장 효율적

 

 

7. Scope

●함수 밖 : 전역영역 ( global )

●함수 안 : 지역영역 ( local )

 

8. 실수할만한 코드 3

data=10

def change():
    data = 20

change()
print(data)
------------
10


#함수 선언 시 설정한 data =20이 나오지 않고
#제일 윗줄에서 설정해준 data =10 이 나왔다.
#data = 20을 사용하고 싶으면 ?

 

#global :지역영역에서 전역영역의 변수사용 방법
data=10

def change():
    global data
    data = 20

change()
print(data)
----------------
20


#가장 위에 data = 10 은 global 데이터 이고, 
#함수 내에 data = 20은 local 데이터이다.
#따라서, 함수에서 만든 data = 20을 쓰기 위해서는
#함수 내에서 'global'을 언급해주어야 한다.
# 지역영역에서 사용되는 변수(식별자)는 지역영역 없으면, 전역영역의 변수를 가져와서 사용
data = 10

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

change()
print('global', data)
---------------------------
local 10
global 10
# return : 전역영역에서 지역영역의 변수 사용하는 방법
data=10

def change():
    data = 20
    return data

data = change()
print(data)
-----------------
20
### 만약 영역이 이중이아니라 3중으로 되어있을 경우  return은 어디 데이터를 가져올까 ?
### -->제일 밖에 있는 전역영역의 데이터를 가져옴
data = 10

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

change1()
--------------------------------
local 10

9. lambda 함수

# 일회성 함수로 간단한 함수(파라미터,리턴) 를 함수 선언 없이 사용 가능 -> 메모리 절약, 가독성 증대

 

1) 기존 함수 

# 변수 3개 선언 : plus, minus, calc : 저장공간 3칸
def plus(n1, n2):
    return n1 + n2

def minus(n1, n2):
    return n1 - n2

def calc(func, n1, n2): #func:plus
    return func(n1, n2)
    


calc(plus, 1, 2), calc(minus, 1, 2)
---------------------------------------
(3, -1)

2)lambda 함수 

# lambda 함수 : 간단한 함수를 함수 선언 없이 사용 가능
func = lambda n1, n2: n1 + n2
func(1, 2)
-------------------------------
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)
 ----------------------------------------------------------------------
 (3, -1)

 

10. list comprehension 

# 간단한 반복문, 조건문을 사용해서 리스트 데이터를 만들 때 사용하는 문법
# 주로 리스트 데이터를 필터링 하거나 데이터를 변경할 때 사용
 
 
 

아래 예시와 같은 반복문을

# 0~9 까지의 데이터에서 홀수만 뽑아서 제곱한 결과를 리스트로 출력
result = []
for num in range(10):
    if num % 2 !=0:
        result.append(num ** 2)
result
--------------------------------------------------------
[1, 9, 25, 49, 81]

 

1줄로 변경 가능

#조건문이 사실일 경우 실행할 내용, for in 문 , if 문

result = [number ** 2 for number in range(10) if number %2]
result
------------------------------------------------------------
[1, 9, 25, 49, 81]

list comprehension

#list comprehension  #간단한 반복문을 '리스트'형태로 만들어주는 것이기 때문에 앞 뒤로 [ ] 필수
reports = ['사업보고서(2020)', '감사보고서(2021)', '[기재정정]사업보고서(2020)']
# 2020년도 보고서 목록을 리스트로 출력
reports_2020 = [report[:-6] for report in reports if report[-5:-1] == '2020']
reports_2020
------------------------------------------------------------------------------
['사업보고서', '[기재정정]사업보고서']

dictionary comprehension

#dictionary comprehension #간단한 반복문을 '딕셔너리'형태로 만들어주는 것이기 때문에 앞 뒤로 { }필수
reports = ['사업보고서(2020)', '감사보고서(2021)', '[기재정정]사업보고서(2020)']
# 2021년도 보고서 목록을 딕셔너리로 출력
reports_2021 = {report[:-6] : report[-5:-1] for report in reports if report[-5:-1] == '2021'}
reports_2021
---------------------------------------------------------------------------------------------
{'감사보고서': '2021'}

데이터 변환 후 리스트로 출력

# kim씨 성을 가진 이름을 연령대로 데이터를 바꿔서 리스트로 출력
names = ['kim python(23)', 'lee notebook(32)', 'kim macbook(47)']
names_kim = [name for name in names if name.split('')[0]]
names_kim




# 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

-------------------------------------------------------------------------
['kim python(20)', 'kim macbook(40)']

for 문 사용하여 작성

# for문 사용하여 작성
names = ['kim python(23)', 'lee notebook(32)', 'kim macbook(47)']

names_kim = [
    name[:-3] + str(int(name[-3:-1]) // 10 * 10) + ')'
    for name in names 
    if name.split(' ')[0] == 'kim'
]

names_kim
-------------------------------------------------------------------
['kim python(20)', 'kim macbook(40)']

 

11. map 함수

# iterable한 데이터의 모든 value에 특정 함수를 적용한 결과를 리스트로 출력

 

728x90

'Python > ▶ Python' 카테고리의 다른 글

TIL ⑤일차  (0) 2023.01.06
TIL ④일차  (0) 2023.01.05
②일차 Quiz - 윤년, Fizzbuzz, left-shift  (0) 2023.01.03
②일차 Quiz - 아이폰과 아이패드  (0) 2023.01.03
TIL ②일차  (2) 2023.01.03