ch05. 함수

728x90

ch05. 함수

05-1. 함수 만들기

[함수의 기본 생성]

def 함수이름 (매개변수) :

코드

[함수 매개변수]

-함수 생성 시 괄호 내부에 입력된 식별자 (매개변수)

-함수 호출 시 매개변수 개수를 일치시켜서 매개값 넣어 호출해주어야 함

 

<매개변수 관련 TypeError> ; 함수 생성 시 매개변수와 호출 시 입력한 매개값 개수 불일치 시 예외

 

[가변 매개변수] : ( *변수 ) 형태

-함수 선언 시, ‘가변 매개변수로 선언해두면,

해당 함수 호출 시 매개변수를 원하는 만큼 넣을 수 있다.

-호출 시 넣은 매개값들을 [리스트]처럼 받는다.

 

def 함수이름 (일반매개, 일반매개, ..., *가변매개):

 

<사용 제약>

- 가변 매개변수 뒤에 일반 매개변수 올 수 X

- 하나의 함수에 가변 매개변수 하나만사용 O

 

[기본 매개변수] : (변수 = ) 형태

함수 선언 시, ‘기본 매개변수를 선언해두면 ,

해당 함수 호출 시, 매개값에 아무 값 넣지 않아도 기본값으로 호출 함수 내부 실행

 

<사용 제약>

-기본 매개변수 뒤에 일반 매개변수 올 수 X

-(가변 매개변수 > 기본 매개변수 함께 사용 시), 가변 우선시됨

: 호출 시 준 매개값들을 모두 가변 매개변수에서 우선적으로 리스트처럼 받아버림

 

[키워드 매개변수]

-매개변수 이름을 직접 지정하여 값을 입력하여 (키워드)처럼 매개변수 주어 호출

-가변 매개변수와 함께 사용해도, 키워드 매개변수로 호출 시 ->기본 매개변수도 값 입력 O

-키워드 매개변수로 기본 매개변수에 필요한 값만 입력 가능O

 

ex) 함수 선언 시 def test (a, b=10, c=20):

함수 호출 시 test(10, c=40, b=2) 호출 -> 키워드 매개변수 사용하여/

함수 호출 시, 값 줄 매개변수 지정해서 필요한 값만 입력 가능

 

[리턴]

-리턴값: 함수의 실행 결과값

 

<반환값 없이 리턴> 그냥 return -> 해당 위치에서 함수 종료 후, 리턴

<반환값 있는 리턴> return 자료 -> 해당 자료를 리턴값으로 반환 후, 리턴

 

[기본적인 함수 활용]

def 함수 (매개변수)

변수 = 초깃값

return 변수

05-2. 함수의 활용

 

[재귀 함수]

함수 내부에서 다시 자기 자신을 재귀적으로 함수 호출

 

<팩토리얼(!) 구현 >

-반복문으로 구현

 

-재귀함수로 구현

#함수 선언

def factorial(n):

# 0! = 1

if n == 0: //재귀함수 호출 종료

return 1

# n! = n * (n-1)!

else:

return n * factorial(n-1)

[재귀함수의 문제]

-문제 : 불필요하게 같은 값 구하는 계산을 여러 번 반복 -> 실행 시간 오래 걸림

 

-해결 : 메모화

-> 한 번 계산한 값은 딕셔너리에 저장(메모)시켜놓고,

이후에 딕셔너리에 해당 값 메모되어 있으면, 중복 처리 없이, 바로 저장된 값 리턴

-> 같은 값을 한 번만 계산하도록 수정된다.

 

#피보나치 수열 a1 =1 , a2 = 1,... an = a(n-1) + a(n-2)

dictionary = { 1:1, 2:1 }



def fibonacci(n):

if n in dictionary: //들어온 n이 딕셔너리에 메모된 값이면

return dictionary[n] //저장된 값 즉시 리턴

else:

output = fibonacci(n-1) + fibonacci(n-2)

dictionary[n] = output //계산한 값은 바로 딕셔너리[n] 에 저장해둠

return output //계산 결과 리턴

 

[조기 리턴]

-흐름 중간에 return을 뒤쪽이 아니라 중간에 사용하는 형태

-들여쓰기 단계가 줄어들어서 가독성 높아짐

 

[global 키워드] : global 변수

-파이썬은 기본적으로 함수 내부에서 함수 외부에 선언된 변수 참조 X

-> 함수 내부에서 함수 외부 변수를 참조,사용할 때 [global 변수] 사용

-> global키워드 붙이면 외부에 선언된 변수를 함수 내부에서도 호환시켜 사용O

05-3. 함수 고급

-파이썬만 가지고 있는 특별한 문법

 

[튜플] tuple

-리스트와 비슷한 자료형, (, 튜플은 한 번 결정된 내부 요소 변경 불가능)

 

<튜플 생성> : () 괄호로 생성하고 쉼표(,)로 구분하여 데이터 요소 나열

 

변수 = ( 데이터, 데이터, 데이터 ...)

 

<튜플 내부 요소 접근> : [] 대괄호로 접근

 

*** <요소 하나만 갖는 튜플 생성>

(273 , ) : 괄호()로 감싼 요소에 쉼표(,)넣어서 선언O

 

<특이한 사용>

(기본) 리스트 생성,선언 : 변수 = [ . . ]

(기본) 튜플 생성,선언 : 변수 = ( , , )

 

(특이) 리스트 생성,선언 : [변수1, 변수2] = [요소1, 요소2]

(특이) 튜플 생성,선언 : (변수1, 변수2) = (요소1, 요소2)

--> 변수 선언된 순서대로 값도 차례로 할당됨

 

<튜플 괄호 생략O>

-유일하게 괄호 생략해도 튜플로 인식O

ex) 변수 = 10, 20, 30, 40

ex) 변수1, 변수2, 변수3 = 10, 20, 30

 

<튜플과 함수>

-함수의 리턴에 튜플 사용 O

-> 튜플 사용하면 여러 개의 값을 한 번에 리턴O, 할당O

-괄호없이 여러 값 할당하는 거은 오직 튜플로만 할 수 있는 일!

 

//함수 선언

def test():

return (10, 20) //튜플 사용하여 2개의 값 한 번에 리턴O

//함수 호출

a, b = test() // 리턴받은 값 2개가 차례로 좌변의 튜플 변수에 할당O

 

<튜플 리턴 함수 사례>

1) enumerate(), items() 함수와 반복문 합쳐서 사용 시 // 반복변수 2개는

 

for i,value in enumerate(리스트) : //(i,value) 형태의 튜플 괄호를 제거한 형태

 

2) divmod() 함수 : 나누기 연산 후, 한 번에 (, 나머지) 튜플 형태로 리턴 함수

a, b = 97, 40

x, y = divmod(a,b) >> (2, 17) 반환해서 차례로 몫, 나머지 변수에 할당

 

[람다]

-람다 : 간단한 함수를 lamda로 쉽게 선언 가능 O

 

-‘함수를 매개변수로 전달할 때 람다사용

-매개변수로 전달될 함수를 람다식으로 변환하여 선언하면 코드 효율적 작성 O

-람다 자체를 함수의 매개변수로 곧바로 넣을 수 O

-람다를 사용 -> 함수가 매개변수로 넣어졌을 때.

넣어진 함수가 어떤 함수인지 알기 위해 다시 올라가서 코드 찾아헤맬 필요 X

----------------------------------------

<람다 선언 구조>

함수이름 = lamda 매개변수 : 리턴값

----------------------------------------

-매개 변수 하나인 람다

output = lamda x : x*x

 

-매개 변수 여러 개인 람다

output = lamda x, y, z : x+y+z

---------------------------------------

 

[람다 사용 프로그램]

 

<매개변수로 함수를 전달하는 대표 표준 함수> : filter() 함수. map() 함수

 

map( 함수, 리스트) : 리스트의 내부 요소 하나하나에 함수가 적용되어 나온 리턴값들을

다시 list() 함수 안에 넣어서 새로운 리스트를 생성

filter( 함수. 리스트) : 리스트의 내부 요소 하나하나에 함수에 적용되어 나온 리턴값들을

다시 list() 함수 안에 넣어서 새로운 리스트를 생성

 

map()함수와 filter()함수를 그대로 출력하면 제너레이터가 나온다.

따라서 list()로 강제 형번환 시켜서 새 리스트 생성하여 출력한다.

 

 

 

[파일 처리]

-파이썬은 파일 처리와 관련된 표준 함수들을 기본으로 제공

-open()함수로 파일을 열면 close()함수로 닫아주어야한다.

<파일 열기> : open() 함수 사용

 

파일 객체 = open( “파일 경로”, “모드 지정”)

 

 

<<파일 모드 지정>>

w : 쓰기 모드

a : 뒤에 이어서 쓰기 모드

r : 읽기 모드

 

<파일 닫기> : close() 함수 사용

 

파일 객체.close()

----------------------------------------------------------------------

<외부 파일에 텍스트 쓰기> write() 함수

 

파일객체.write()

 

<외부 파일의 텍스트 읽기> read() 함수

-파일 내부에 있는 데이터 모두 읽어서 출력하는 함수

 

파일객체.read()

 

-----------------------------------------------------------------------

<<with 키워드>>

: open() 함수로 파일 열고 close() 함수로 파일 닫지 않는 경우

: with 키워드 사용 시 -> 구문 종료 시 자동 close() 함수 호출하여 파일 닫음

 

with open(“파일 경로”, “모드”) as 파일객체:

문장

 

<<스트림>>

: 프로그램이 외부의 (파일or네트워크)와 통신할 때 데이터가 흐르는 길

open() 함수는 프로그램에서 외부로 향하는 스트림을 열어주고

close() 함수는 외부에서 프로그램으로 향하는 스트림을 닫는다

 

----------------------------------------------------------------------

 

[제너레이터]

-제너레이터: 이터레이터를 직접 만들 때 사용하는 코드

-제너레이터 객체: 함수의 코드를 조금씩 실행 할 때 사용O (메모리 효율성)

 

-함수 내부에 [yeild 키워드]를 사용하면 해당 함수는 제너레이터 함수가 됨

-제너레이터 함수는 그냥 호출 -> 함수 내부 코드 실행 X

-제너레이터 함수는 제너레이터 객체를 리턴함

제너레이터 객체에 next()함수를 사용 -> 함수 내부의 yeild 키워드 까지만 실행O

->함수의 코드를 yeild 키워드를 기준으로 조금씩 실행됨

 

제너레이터 객체에 next()함수 리턴값 출력 -> yeild키워드 뒤에 입력한 값 출력O

->next() 호출 한 뒤 yeild 키워드 만나지 못하면

--> <StopIteration 예외 발생>

 

#제너레이터 함수 선언

def test():

print("A지점 통과 ")

yield 1

print("B지점 통과")

yield 2

print("C지점 통과")

 

#제너레이터 함수 그냥 호출 -> 제너레이터 객체 리턴

output = test()

#next() 함수 호출 -> yield 기준으로 함수 코드 조금씩 실행시킴

a = next(output)

print(a) #next()함수 리턴값 = yield 키워드 뒤 입력값

 

b = next(output)

print(b)

 

c = next(output)

print(c) #이 부분에서 <StopIteration 예외 발생>

 

[파일 열어서 데이터 저장 후 출력]

#1000명의 (이름.몸무게.) 랜덤 데이터 write() 쓰기

#CSV : 한 줄에 쉼표 사용하여 i의 데이터들을 나열하여 표현

 

import random

hanguls = list("가나다라마바사아자차카타하")

 

with open("info.txt", "w") as file:

for i in range(1000):

#랜덤값 받아서 데이터 변수 생성

name = random.choice(hanguls) + random.choice(hanguls)

weight = random.randrange(40,100)

height = random.randrange(140,200)

#외부 파일에 CSV형태로 데이터 쓰기

file.write("{}, {}, P[\n".format(name,weight,height)]

#앞에서 저장한 파일 열어서 line담위로 파일 내부 데이터 read() 읽기

with open("info.txt", "r") as file:

for line in file:

#변수 선언

(name, weight, height) = line.strip().split(",")

#파일에서 읽는 데이터에 누락된 값 있는 경우 건너뛰고 다음 데이터 읽음

if (not name) or (not weight) or (not height):

continue

 

#파일에서 읽은 데이터들로 bmi 계산하여 체중 분류

bmi = int(weight) / ((int(height) / 100) **2)

result = ""

if 25 <= bmi:

result = "과체중"

elif 18.5<=bmi:

result = "정상체중"

else:

result = "저체중"



#출력

print('\n'.join([

"이름:{}",

"몸무게: {}",

"키:{}",

"BMI: {}",

"결과: {}"

]).format(name, weight, height, bmi, result))

print()

 

728x90

'Python > [문법]_Python(파이썬)' 카테고리의 다른 글

ch04. 반복문  (0) 2021.09.05
ch03. 조건문  (0) 2021.09.05
ch02. 자료형  (0) 2021.09.03
ch01. 파이썬 시작  (0) 2021.08.31