python - 혼자 공부하는 파이썬

jsbak·2022년 9월 14일
0

PYTHON

목록 보기
24/24

이름 짓기 식별자(변수, 클래스 등등) 는 함수, 변수는 snake case 클래스는Camel case 인데 Camel case 에서 유의 사항은 첫번 째 단어의 첫 글자도 대문자로 처리한다.

자료를 알아야하는 이유

  • 자료가 모여 더 큰 자료형이 되고 이것이 모여 프로그램을 이루기 때문.
  • 시퀀스 형 - list, tuple, range
    매핑 형 - dict ( 리스트, tuple )

파이썬에서 자료형 확인

type() 함수 이용

print(type("안녕하세요"))
# <class 'str'>
print(type(273))
# <class 'int'>

여러 문자열 넣는 법

  1. \n 를 이용해서 줄바꿈
  2. """ <문자열 내용> """
print("동해물과 백두산이\n 마르고 닳도록")
동해물과 백두산이
 마르고 닳도록
print("""동해물과 백두산이
마르고 닳도록""")
동해물과 백두산이
마르고 닳도록
  • 줄 바꾸지 않겠다고 선언하는 방법
    \ 이용?

문자열 연산

문자열 연결 연산자 +

  • 문자열 끼리 + 연산 가능
  • 문자열 + 숫자 + 연산 불가능
print("안녕" + "하세요")
# 안녕하세요
print("안녕하세요" + 1)
# TypeError: can only concatenate str (not "int") to str

문자열 반복 연산자 *

  • 숫자 문자열, 문자열 숫자
    • 숫자만큼 문자열을 반복
print(3 * "안녕하세요")
안녕하세요안녕하세요안녕하세요

문자 선택 연산자(인덱싱): []

print("문자 선택 연산자에 대해 알아볼까요?")
print("안녕하세요"[0])
print("안녕하세요"[1])
print("안녕하세요"[2])
print("안녕하세요"[3])
print("안녕하세요"[4])
[0][1][2][3][4]
print("문자 선택 연산자에 대해 알아볼까요?")
print("안녕하세요"[-5])
print("안녕하세요"[-4])
print("안녕하세요"[-3])
print("안녕하세요"[-2])
print("안녕하세요"[-1])
[-5][04][-3][-2][-1]

문자열 범위 선택 연산자(슬라이싱): [:]

print("안녕하세요"[1:4])
녕하세

문자열의 길이 구하기

len(문자열)

print(len("안녕하세요"))
5

숫자

제곱 연산자: **

**: 2^4 는 2**4로 씁니다.

TypeError 예외

서로 다른 자료를 연산 하면 TypeError 예외 발생

사용자 입력: input()

input(): 사용자로부터 데이터를 입력 받는 함수

  • input() 함수의 입력 자료형 : 무조건 문자열

문자열을 숫자로 바꾸기 (캐스팅)

  • int(): 문자열을 int 자료형으로 변환
  • float(): 문자열을 floast 자료형으로 변환
string_a = input("입력A> ")

int_a = int(string_a)

string_b = input("입력B> ")
int_b = int(string_b)

print("문자열 자료:", string_a + string_b)
print("숫자 자료:", int_a + int_b)
print("int_a:", type(int_a))
print("int_b:", type(int_b))

ValueError 예외

  • 자료형을 '변환할 수 없는 것'으로 변환하려고 할때 발생
  1. 숫자가 아닌 것을 숫자로 변환하려고 할 때

    int("안녕하세요")
    float("안녕하세요")
    # ValueError: invalid literal for int() with base 10: '안녕하세요'

  2. 소수점이 있는 숫자 형식의 문자열을 int() 함수로 변환하려고 할 때

    init("52.273")
    # ValueError: invalid literal for int() with base 10: '52.273'

숫자를 문자열로 바꾸기

  • str(다른 자료형)

02-4. 숫자와 문자열의 다양한 함수

문자열의 format() 함수

  • 문자열이 가지고 있는 함수
  • 문자열로 변환하는 함수
  • 문자열의 {} 기호가 format() 함수 괄호 안에 있는 매개 변수1대1 매칭
  • 중괄호의 개수와 format 함수 괄호 안 매개변수의 개수는 반드시 같아야 한다.

    "{}".format(10)
    "{} {}".format(10, 20)
    "{} {} {} {} {}".format(101, 202 ,303, 404, 505)

IndexError 예외

{} 기호의 개수가 format() 함수의 매개변수 개수 보다 많으면 발생

format() 함수의 다양한 기능

정수 출력의 다양한 형태

  • {:d} 는 int 자료형의 정수를 출력하겠다고 직접적으로 지정하는 것
  • {:nd} 는 n칸을 빈 칸으로 잡고 뒤에서부터 52라는 숫자를 채운다.
  • {:0d} 라고 지정하면 7칸을 잡고 뒤에서부터 52라는 숫자를 넣은 후, 앞의 빈 곳을 부호가 있을 때는 맨 앞자리에 부호로 채우고 나머지 빈 곳을 0으로 채운다.
# 정수 
output_a = "{:d}".format(52)

# 특정 칸에 출력하기
output_b = "{:5d}".format(52)       # 5칸
output_c = "{:10d}".format(52)      # 10칸

# 빈칸을 0으로 채우기
output_d = "{:05d}".format(52)      # 양수
output_e = "{:05d}".format(-52)     # 음수

print("# 기본")
print(output_a)
print("# 특정 칸에 출력하기")
print(output_b)
print(output_c)
print("# 빈칸을 0으로 채우기")
print(output_d)
print(output_e)
###############
# 기본
52
# 특정 칸에 출력하기
   52
        52
# 빈칸을 0으로 채우기
00052
-0052
  • d 앞에 +기호를 붙이면 양수와 음수 기호를 표현할 수 있습니다.
  • {: d} 처럼 앞에 공백을 두어 기호 위치를 비워 주면 함수에 입력한 기호가 표현
# 기호와 함께 출력하기
output_f = "{:+d}".format(52)   # 양수
output_g = "{:+d}".format(-52)  # 음수
output_h = "{: d}".format(52)   # 양수: 기호 부분 공백
output_i = "{: d}".format(-52)  # 음수: 기호 부분 공백

print("# 기호와 함꼐 출력하기")
print(output_f)
print(output_g)
print(output_h)
print(output_i)
  • 기호와 공백을 조합할 때는 = 기호를 앞에 붙일 수 있다.
# 조합하기
output_h = "{:+5d}".format(52)      # 기호를 뒤로 밀기: 양수
output_i = "{:+5d}".format(-52)     # 기호를 뒤로 밀기: 음수
output_j = "{:=+5d}".format(52)     # 기호를 앞으로 밀기: 양수
output_k = "{:=+5d}".format(-52)    # 기호를 앞으로 밀기: 음수
output_l = "{:+05d}".format(52)     # 0으로 채우기: 양수
output_m = "{:+05d}".format(-52)    # 0으로 채우기: 음수

print("# 조합하기")
print(output_h)
print(output_i)
print(output_j)
print(output_k)
print(output_l)
print(output_m)

💢 조합 순서가 중요하다.

부동 소수점 출력의 다양한 형태

  • {:f} : float 자료형 출력
  • {:line.nf} : 소수점 n자리까지 지정, 자동 반올림
output_a = "{:15.3f}".format(52.273)
output_b = "{:15.2f}".format(52.273)
output_c = "{:15.1f}".format(52.273)

print(output_a)
print(output_b)
print(output_c)

의미 없는 소수점 제거

  • {:g} : 의미 없는 0을 제거하고 출력
output_a = 52.0
output_b = "{:g}".format(output_a)
print(output_a)
print(output_b)

대소문자 바꾸기: upper()와 lower()

  • upper() 문자열의 알파벳을 대문자로 변경
  • lower() 문자열의 알파벳을 소문자로 변경
  • 두함수 모두 원본은 변화 시키지 않고 새로 만든 문자열을 반환한다.

문자열 양옆의 공백 제거하기: strip()

  • strip() 문자열 양옆의 공백 제거
  • lstrip() 문자열 왼쪽의 공백 제거
  • rstrip() 문자열 오른쪽의 공백 제거
  • 공백이란? 띄어쓰기, 탭, 줄바꿈을 모두 포함
>>> input_a = """
	안녕하세요
문자열의 함수를 알아봅니다
"""
>>> print(input_a)

	안녕하세요
문자열의 함수를 알아봅니다

>>> print(input_a.strip())
안녕하세요
문자열의 함수를 알아봅니다
>>> 

이러한 공백 제거 기능을 trim 이라고 부르고 lstrip()rstrip() 은 거의 사용하지 않음.

문자열의 구성 파악하기: isOO()

  • isalnum(): 문자열이 알파벳 또는 숫자로만 구성되어 있는지 확인
  • isalpha(): 문자열이 알파벳으로만 구성되어 있는지 확인
  • isdentifier(): 문자열이 식별자로 사용할 수 있는 것인지 확인
  • isdecimal(): 문자열이 정수 형태인지 확인
  • iddigit(): 문자열이 숫자로 인식될 수 있는 것인지 확인
  • isspace(): 문자열이 공백으로만 구성되어 있는지 확인
  • islower(): 문자열이 소문자로만 구성되어 있는지 확인
  • isupper(): 문자열이 대문자로만 구성되어 있는지 확인
>>> print("TrainA10".isalnum())
True
>>> print("10".isdigit())
True

문자열 찾기: find()와 rfind()

문자열 내부에 특정 문자가 어디에 위치하는지 확인할 때

  • find(): 왼쪽부터 찾아서 처음 등장하는 위치를 반환
  • rfind(): 오른쪽부터 찾아서 처음 등장하는 위치를 반환
output_a = "안녕안녕하세요".find("안녕")
print(output_a)
0
output_b = "안녕안녕하세요".rfind("안녕")
print(output_b)
2

문자열과 in 연산자

  • in 연산자 : 문자열 내부에 어떤 문자열이 있는지 확인, True/False 를 반환
>>> print("안녕" in "안녕하세요")
True
>>> print("잘자" in "안녕하세요")
False

문자열 자르기: split()

  • split() : 문자열을 특정한 문자로 자를 때
    • 괄호 안의 문자열인 공백(띄어쓰기)을 기준으로 자른다.
  • 실행 결과로 리스트(list) 반환
>>> a = "10 20 30 40 50".split(" ")  
>>> print(a)
['10', '20', '30', '40', '50']

f-문자열

파이썬 3.6 부터는 format() 함수를 더 간단하게 사용할 수 있는 방법을 제공 f-문자열

>>>"문자열{}문자열".format("크 10") 
'문자열크 10문자열'
>>>f'문자열{"크 10"}문자열'
'문자열크 10문자열'

f-문자열보다 format() 함수를 사용하는 것이 더 좋은 경우

1. 문자열 내용이 너무 많은 경우

>>> name = "구름"
      
>>> age = 7
      
>>> """# 문자열이 너무 긴 경우
문자열이 너무 긴 상활에서
데이터 {}을/를 출력해야 하는 경우가 있습니다.

이때 f-문자열을 사용하면
어떤 위치에 어떤 데이터 {}가 출력되는지 확인하기 위해서
문자열 전체를 읽어야 하는 문제가 있습니다.
이러한 경우 format() 함수를 사용하는 것이 편리합니다.
문자열이 아무리 길어도 다음 줄만 보면
어떤 데이터를 출력하는지 쉽게 알 수 있습니다.
""".format(name, age) # ➡ format() 함수로 삽입할 데이터를 가리킵니다.
      
'# 문자열이 너무 긴 경우\n문자열이 너무 긴 상활에서\n데이터 구름을/를 출력해야 하는 경우가 있습니다.\n\n이때 f-문자열을 사용하면\n어떤 위치에 어떤 데이터 7가 출력되는지 확인하기 위해서\n문자열 전체를 읽어야 하는 문제가 있습니다.\n이러한 경우 format() 함수를 사용하는 것이 편리합니다.\n문자열이 아무리 길어도 다음 줄만 보면\n어떤 데이터를 출력하는지 쉽게 알 수 있습니다.\n'

2. 데이터를 리스트에 담아서 사용할 때

`['별', 2, 'M', '서울특별시 강서구', 'Y'] 와 같이 데이터를 리스트에 담아서 사용하는 경우 format() 사용하는 것이 좋음

>>> data = ['별', 2, 'M', '서울특별시 강서구', 'Y']
     
>>> f"""이름: {data[0]}
나이: {data[1]}
성별: {data[2]}
지역: {data[3]}
중성화 여부: {data[4]}"""
     
'이름: 별\n나이: 2\n성별: M\n지역: 서울특별시 강서구\n중성화 여부: Y'
>>> data = ['별', 2, 'M', '서울특별시 강서구', 'Y']
 
>>> """이름: {}
나이: {}
성별: {}
지역: {}
중성화 여부: {}""".format(*data) # * 전개 연산자: 리스트를 전개한다.
     
'이름: 별\n나이: 2\n성별: M\n지역: 서울특별시 강서구\n중성화 여부: Y'

Chapter3

  • 모듈 기능을 이요해 datetime이라는 기능을 가져와 datetime.datetime.now() 함수로 현재의 시간을 구한다.

날짜/시간 활용하기

# 날짜/시간과 관련된 기능을 가져옵니다.
import datetime

# 현재 날짜/시간을 구합니다.
now = datetime.datetime.now()

# 출력합니다.
print(now.year, "년")
print(now.month, "월")
print(now.day, "일")
print(now.hour, "시")
print(now.minute, "분")
print(now.second, "초")

날짜/시간을 한 줄로 출력하기

# 날짜/시간과 관련된 기능을 가져옵니다.
import datetime

# 현재 날짜/시간을 구합니다.
now = datetime.datetime.now()

# 출력합니다.
print("{}년 {}월 {}일 {}시 {}분 {} 초".format(
    now.year,
    now.month,
    now.day,
    now.hour,
    now.minute,
    now.second
))

짝수와 홀수 구분

  • \ 줄이 길어져 줄을 바꿀때 사용
# 입력을 받습니다.
number = input("정수 입력> ")

# 마지막 자리 숫자를 추출
last_character = number[-1]

# 숫자로 변환하기
last_number = int(last_character)

# 짝수 확인
if last_number == 0 \
    or last_number == 2 \
    or last_number == 4 \
    or last_number == 6 \
    or last_number == 8:
    print("짝수 입니다.")

# 홀수 확인
if last_number == 1 \
    or last_number == 3 \
    or last_number == 5 \
    or last_number == 7 \
    or last_number == 9:
    print("홀수 입니다.")
  • in 연산자 이용하여 내부 문자열 확인
# 입력을 받습니다.
number = input("정수 입력> ")

# 마지막 자리 숫자를 추출
last_character = number[-1]

# 짝수 확인
if last_character in "02468":
    print("짝수 입니다.")

# 홀수 확인
if last_character in "13579":
    print("홀수 입니다.")
  • 나머지 연산자를 활용해서 짝수와 홀수 구분
# 입력을 받습니다.
number = input("정수 입력> ")
number = int(number)

# 짝수 확인
if number % 2 == 0:
    print("짝수 입니다.")

# 홀수 확인
if number % 2 == 1:
    print("홀수 입니다.")

💢 컴퓨터에서는 어떻게 하는 게 더 빠를까 를 고민 💢

False로 변환되는 값

  • None, 숫자 0, 0.0, 빈 컨테이너(빈 문자열, 빈 바이트열, 빈 리스트, 빈 튜플, 빈 딕셔너리 등) 을 제외한 모두는 True로 변환

Pass 키워드

  • pass 키워드를 넣으면 코드를 작성하지 않아도 그냥 넘어간다.
  • 프로그래밍의 골격을 잡아 놓고, 내부 처리 로직은 나중에 만들고 싶은 경우 사용

raise NotImplementedError

아직 구현하지 않았다며 오류를 강제로 발생 시킬 수 있다.

리스트

  • 여러가지 자료를 저장할 수 있느 자료
  1. 대괄호 안에 음수를 넣어 뒤에서 부터 요소를 선택 가능
  2. 리스트 접근 연산자를 다음과 같이 이중으로 사용가능
>>> list_a = [273, 32, 103, "문자열", True, False]
>>> list_a[3]
'문자열'
>>> list_a[3][0]
'문'
  1. 리스트 안에 리스트를 사용 가능
>>> list_a = [[1,2,3], ...]

리스트에서의 IndexError 예외

>>> list_a = [273, 32, 103]
>>> list_a[3]
IndexError: list index out of range

리스트 연산하기: 연결(+), 반복(*), len()

# 리스트를 선언합니다.
list_a = [1,2,3]
list_b = [4,5,6]

# 출력합니다.
print("# 리스트")
print("list_a = ", list_a)
print("list_b = ", list_b)
print()

# 기본 연산자
print("# 리스트 기본 연산자")
print("list_a + list_b =", list_a + list_b)
print("list_a * 3 =", list_a * 3)
print()

# 함수
print("# 길이 구하기")
print("len(list_a) =", len(list_a))

####################################################
# 리스트
list_a =  [1, 2, 3]
list_b =  [4, 5, 6]

# 리스트 기본 연산자
list_a + list_b = [1, 2, 3, 4, 5, 6]
list_a * 3 = [1, 2, 3, 1, 2, 3, 1, 2, 3]

# 길이 구하기
len(list_a) = 3
  • len() 함수는 괄호 내부에 문자열을 넣으면 문자열의 글자 수(=길이)를 세어 주지만, 리스트 변수를 넣으면 요소의 개수를 세어 줍니다.

리스트에 요소 추가하기: append(), insert()

  • append(): 리스트 뒤에 요소 추가
    • 리스트명.append(요소)
  • insert(): 리스트의 중간에 요소 추가
    • 리스트명.insert(위치, 요소)
# 리스트를 선언합니다.
list_a = [1, 2, 3]

# 리스트 뒤에 요소 추가하기
print("# 리스트 뒤에 요소 추가하기")
list_a.append(4)
list_a.append(5)
print(list_a)
print()

# 리스트 중간에 요소 추가하기
print("# 리스트 중간에 요소 추가하기")
list_a.insert(0, 10)
print(list_a)

##################################################
# 리스트 뒤에 요소 추가하기
[1, 2, 3, 4, 5]

# 리스트 중간에 요소 추가하기
[10, 1, 2, 3, 4, 5]
  • extend(): 한 번에 여러 요소 추가, 리스트를 받아 기존 리스트 뒤에 새로운 리스트의 요소를 모두 추가
    • 원본 리스트를 수정
>>> list_a = [1,2,3]
>>> list_a.extend([4,5,6])
>>> print(list_a)
[1,2,3,4,5,6]

리스트에 요소 제거하기

  • 인덱스로 제거하기
  • 값으로 제거하기

인덱스로 제거하기: del 키워드, pop()

요소의 위치 기반으로 요소를 제거하는 것, del 키워드 또는 pop() 함수 사용

  • del 키워드는 리스트의 특정 인덱스에 있는 요소를 제거
    del 리스트명[인덱스]
  • pop() 함수는 제거할 위치에 있는 요소를 제거하는데, 매개변수를 입력하지 않으면 -1이 들어가는 것으로 취급해서 마지막 요소를 제거
    리스트명.pop(인덱스)
list_a = [0,1,2,3,4,5]
print("# 리스트의 요소 하나 제거하기")

# 제거 방법[1] - del 키워드
del list_a[1]
print("del list_a[1]:", list_a)

# 제거 방법[2] - pop()
list_a.pop(2)
print("pop(2):", list_a)
###################################################
# 리스트의 요소 하나 제거하기
del list_a[1]: [0, 2, 3, 4, 5]
pop(2): [0, 2, 4, 5]
  • del 키워드는 범위를 지정해 리스트의 요소를 한꺼번에 제거할 수도 있다.
>>> list_b = [0,1,2,3,4,5,6]
>>> del list_b[3:6]
>>> list_b
[0,1,2,6]

>>> list_c = [0,1,2,3,4,5,6]
>>> del list_c[:3]
>>> list_c
[3,4,5,6]

>>> list_d = [0,1,2,3,4,5,6]
>>> del list_c[3:]
>>> list_d
[0, 1, 2]

리스트 슬라이싱

  • 슬라이싱: 리스트에 [:] 연산자로 리스트 범위를 지정하여 여러 요소를 선택하는 것
    리스트[시작_인덱스:끝_인덱스:단계]
    문자열 슬라이싱과 사용법 동일
    • 마지막 위치에는 '단계'라는 부분 추가 가능한데 단계를 지정하면 지정한 숫자만큼 인덱스를 건너뛰며 요소를 가져온다.
    • 단계를 -1 로 설정하면 반대로 출력
>>> numbers = [1,2,3,4,5,6,7,8]
>>> numbers[0:5:2]
[1,3,5]
>>> numbers = [1,2,3,4,5,6,7,8]
>>> numbers = [::-1] # 시작 인덱스와 끝 인덱스는 자동으로 "전부"가 지정됩니다.
>>> [8,7,6,5,4,3,2,1,0] # 단계가 -1 이므로 반대로 출력합니다.

값으로 제거하기: remove()

  • remove(): 값으로 제거
    리스트.remove(값)
    remove() 함수로 지정한 값이 리스트 내부에 여러개 있어도 가장 먼저 발견되는 하나만 제거
>>> list_c = [1,2,1,2]	# 리스트 선언하기
>>> list_c.remove(2)	# 리스트의 요소를 값으로 제거하기
>>> list_c
[1,1,2]

모두 제거하기: clear()

  • clear(): 리스트 내부의 요소를 모두 제거
    리스트.clear()
>>> list_d = [0,1,2,3,4,5]
>>> list_d.clear()
>>> list_d
[] -> 요소가 모두 제거

리스트 정렬하기: 라스트.sort(), sorted(리스트)

sort(): 리스트 요소를 정렬, 기본 오름차순 정렬
리스트.sort()

리스트.sort()와 sorted(리스트)의 가장 큰 차이는 리스트.sort() 는 본체의 리스트를 정렬해서 변환하는 것이고, sorted(리스트) 는 본체 리스트는 내버려두고, 정렬한 새로운 리스트를 반환하는 것입니다.

  • sorted(정렬할 데이터)
    sorted(정렬할 데이터, reverse 파라미터)
    sorted(정렬할 데이터, key 파라미터)
    sorted(정렬할 데이터, key 파라미터, reverse 파라미터)
    sorted 함수는 파이썬 내장 함수입니다.첫 번째 매개변수로 들어온 이터러블한 데이터를 새로운 정렬된 리스트로 만들어서 반환해 주는 함수입니다.
  • 첫 번째 매개변수로 들어올 "정렬할 데이터"는 iterable 한 데이터 이어야 합니다.

Chapter 5

함수

  • 코드의 집합

함수 기본형

def  함수 이름():
	문장

매개변수 있는 함수

  • 매개변수는 함수 생성 시 괄호 내부에 식별자를 입력해 만듬.
def 함수 이름(매개변수, 매개변수, ...):
	문장

매개변수와 관련된 TypeError

# 매개변수를 2개 지정
def print_n_tiems(value, n):
	for i in range(n):
    	print(value)
        
# 함수를 호출합니다.
print_n_times("안녕하세요") # 인자 하나만 넣음

#################################################
TypeError: print_n_times() missing 1 required positional argument: 'n'
# 매개변수를 2개 지정
def print_n_tiems(value, n):
	for i in range(n):
    	print(value)
        
# 함수를 호출합니다.
print_n_times("안녕하세요", 10, 20) # 인자 3개 넣음

#################################################
TypeError: print_n_times() takes 2 positional arguments but 3 were given

가변 매개변수

  • 가변 매개변수 함수: 매개변수를 원하는 만큼 받을 수 있는 함수
  • 제약
    • 가변 매개변수 뒤에는 일반 매개변수가 올 수 없다.
    • 가변 매개변수는 하나만 사용가능
def 함수 이름(매개변수, 매개변수, ..., *가변 매개변수):
	문장

기본 매개변수

  • 기본 매개변수: '매개변수=값' 형태
  • 기본 매개변수 뒤에는 일반 매개변수가 올 수 없다.
    • 기본 매개변수를 생략 했을때 매개변수가 어디에 할당되야하는지 알수 없기 때문
def print_n_times(value, n=2):
    # n번 반복합니다.
    for i in range(n):
        print(value)

# 함수를 호출합니다.
print_n_times("안녕하세요")

키워드 매개변수

기본 매개변수가 가변 매개변수보다 앞에 올 때

  • 기본 매개변수가 가변 매개변수보다 앞에 올 때는 기본 매개변수의 의미가 사라진다.
def print_n_times(n=2, *values):
    # n번 반복합니다.
    for i in range(n):
        # values는 리스트처럼 활용합니다.
        for value in values:
            print(value)
        # 단순한 줄바꿈
        print()

# 함수를 호출합니다.
print_n_times("안녕하세요", "즐거운", "파이썬 프로그래밍")
#################################################
Traceback (most recent call last):
  File "<pyshell#15>", line 2, in <module>
    print_n_times("안녕하세요", "즐거운", "파이썬 프로그래밍")
  File "<pyshell#14>", line 3, in print_n_times
    for i in range(n):
TypeError: 'str' object cannot be interpreted as an integer

매개변수가 순서대로 입력되기 때문에 n 자리에 '안녕하세요'가 들어가 버린다 따라서 에러 발생

가변 매개변수가 기본 매개변수보다 앞에 올 때

  • 가변 매개변수가 우선시 된다.
def print_n_times(*values, n=2):
    # n 번 반복합니다.
    for i in range(n):
        # values는 리스트처럼 활용합니다.
        for value in values:
            print(value)
        #단순한 줄바꿈
        print()

        
# 함수를 호출합니다.
print_n_times("안녕하세요", "즐거운", "파이썬 프로그래밍", 3)
#################################################
안녕하세요
즐거운
파이썬 프로그래밍
3

안녕하세요
즐거운
파이썬 프로그래밍
3

키워드 매개변수

  • print_n_times("안녕하세요", "즐거운", "파이썬 프로그래밍", n=3)
    • n=3: 매개변수 n 이라고 키워드 명시를 했다.
def print_n_times(*values, n=2):
    # n번 반복합니다.
    for i in range(n):
        # values는 리스트처럼 활용합니다.
        for value in values:
            print(value)
        # 단순한 줄바꿈
        print()

# 함수를 호출합니다.
print_n_times("안녕하세요", "즐거운", "파이썬 프로그래밍", n=3)
기본 매개변수 중에 필요한 값만 입력하기
  • 여러 함수 호출 형태
def test(a, b = 10, c = 100):
    print(a + b + c)

# 1) 기본 형태
test(10, 20, 30)
# 2) 키워드 매개변수로 모든 매개변수를 지정한 형태
test(a = 10, b = 100, c = 200)
# 3) 키워드 매개변수로 모든 매개변수를 마구잡이로 지정한 형태
test(c=10, a=100, b=200)
# 4) 키워드 매개변수로 일부 매개변수만 지정한 형태
test(10, c=200)

리턴

  • 함수의 결과

자료 없이 리턴하기

return 키워드 : 함수를 실행했던 위치로 돌아가라, 함수가 끝나는 위치를 의미

# 함수를 정의합니다.
def return_test():
    print("A 위치입니다.")
    return                       # 리턴합니다.
    print("B 위치입니다.")

# 함수를 호출합니다.
return_test()

#################################################
A 위치입니다.

자료와 함께 리턴하기

# 함수를 정의합니다.
def return_test():
    return 100

# 함수를 호출합니다.
value = return_test()
print(value)

아무것도 리턴하지 않기

  • None 출력
    • None : 없다.
# 함수를 정의합니다.
def return_test():
    return

# 함수를 호출합니다.
value = return_test()
print(value)

기본적인 함수의 활용

def 함수(매개변수):
	변수 = 초깃값
    # 여러 가지 처리
    # 여러 가지 처리
    # 여러 가지 처리
    return 변수
  • 기본 매개변수와 키워드 매개변수를 활용해 범위의 정수를 더하는 함수
# 함수를 선언합니다.
def sum_all(start=0, end=100, step=1):
    # 변수를 선언합니다.
    output = 0
    # 반복문을 돌려 숫자를 더합니다.
    for i in range(start, end + 1, step):
        output += i
    
    # 리턴합니다.
    return output

# 함수를 호출합니다.
print("A.", sum_all(0,100,10))
print("B.", sum_all(end=100))
print("C.", sum_all(end=100, step=2))

함수의 활용

재귀함수

  • 재귀 : 자기 자신을 호출하는 것

반복문으로 팩토리얼 구하기

# 함수를 선언합니다.
def factorial(n):
    # 변수를 선언합니다.
    output = 1
    # 반복문을 돌려 숫자를 더합니다.
    for i in range(1, n + 1):
        output *= i
    # 리턴합니다.
    return output

# 함수를 호출합니다.
print("1!:", factorial(1))
print("2!:", factorial(2))
print("3!:", factorial(3))
print("4!:", factorial(4))
print("5!:", factorial(5))

재귀 함수로 팩토리얼 구하기

# 함수를 선언합니다.
def factorial(n):
    # n이 0이라면 1을 리턴
    if n == 0:
        return 1
    # n이 0이 아니라면 n * (n-1)!을 리턴
    else:
        return n * factorial(n-1)

# 함수를 호출합니다.
print("1!:", factorial(1))
print("2!:", factorial(2))
print("3!:", factorial(3))
print("4!:", factorial(4))
print("5!:", factorial(5))

재귀 함수의 문제

  • 상황에 따라서 기하급수적으로 반복할 수 있음.

  • 메모리화

  • 재귀 함수로 구현한 피보나치 수열(1)

# 함수를 선언합니다.
def fibonacci(n):
    if n == 1:
        return 1
    if n == 2:
        return 1
    else:
        return fibonacci(n-1) + fibonacci(n-2)

# 함수를 호출합니다.
print("fibonacci(1):", fibonacci(1))
print("fibonacci(2):", fibonacci(2))
print("fibonacci(3):", fibonacci(3))
print("fibonacci(4):", fibonacci(4))
print("fibonacci(5):", fibonacci(5))
    
  • 재귀 함수로 구현한 피보나치 수열(2)
    • 아래 코드는 한 번 구했던 값이라도 처음부터 다시 계산해야한다. 그래서 기하급수적으로 계산 횟수가 증가.
# 변수를 선언합니다.
counter = 0

# 함수를 선언합니다.
def fibonacci(n):
    # 어떤 피보나치 수를 구하는지 출력합니다.
    print("fibonacci({})를 구합니다.".format(n))
    global counter
    counter += 1
    # 피보나치 수를 구합니다.
    if n == 1:
        return 1
    if n == 2:
        return 1
    else:
        return fibonacci(n-1) + fibonacci(n-2)

# 함수를 호출합니다.
fibonacci(10)
print("---")
print("fibonacci(10) 계산에 활용된 덧셈 횟수는 {}번입니다.".format(counter))    

UnboundLocalError에 대한 처리

# 변수를 선언합니다
counter = 0

# 함수를 선언합니다.
def fibonacci(n):
    counter += 1 # 함수 외부에 있는 변수
    # 피보나치 수를 구합니다.
    if n == 1:
        return 1
    if n == 2:
        return 1
    else:
        return fibonacci(n - 1) + fibonacci(n - 2)

# 함수를 호출합니다.
print(fibonacci(10))
#################################################
Traceback (most recent call last):
  File "d:\source\python\hongong-python\chap05\fibonacci_recursion03.py", 
line 16, in <module>
    print(fibonacci(10))
  File "d:\source\python\hongong-python\chap05\fibonacci_recursion03.py", 
line 6, in fibonacci
    counter += 1
UnboundLocalError: local variable 'counter' referenced before assignment  
  • 파이썬은 함수 내부에서 함수 외부에 있는 변수(Ex. counter)를 참조하지 못한다. 함수 내부에서 함수 외부에 있는 변수라는 것을 설명하려면 global 변수이름 라는 구문을 사용한다.
  • global 키워드는 파이썬 프로그래밍 언어에만 있는 특이한 구조이다. global을 쓰지 않고 썻다가. W0621L Redefining name 'counter' from outer scope 또는 E0602: Undefined variable 'counter' 가 나타나면 global 를 써주도록 코드를 수정

메모화

  • 재귀함수에서 같은 값을 구하는 연산을 반복하기 때문에 재귀가 많아 질수록 성능 저하가 발생합니다.
    이는 같은 값을 한번만 계산하도록 코드를 수정
# 메모 변수를 만듭니다.
dictionary = {
    1: 1,
    2: 2
}

counter = 0

# 함수를 선언합니다.
def fibonacci(n):
    if n in dictionary:
        # 메모가 되어 있으면 메모된 값을 리턴
        return dictionary[n]
    else: 
        # 메모가 되어 있지 않으면 값을 구함
        output = fibonacci(n - 1) + fibonacci(n - 2)
        dictionary[n] = output
        return output

# 함수를 호출합니다.
print("fibonacci(10):", fibonacci(10))
print("fibonacci(20):", fibonacci(20))
print("fibonacci(30):", fibonacci(30))
print("fibonacci(40):", fibonacci(40))
print("fibonacci(50):", fibonacci(50))
  • 딕셔너리를 사용해서 한 번 계산한 값을 저장, 이를 메모 한다고 표현하며 메모된 값이 있으면 처리를 수행 하지 않고 메모된 값을 반환함으로써 코드의 속도를 빠르게 만듬.
    • 30 번 기준
      • 재귀 함수: 1664079 번
      • 메모화: 28 번

조기 리턴

  • 필요할 때 return 키워드를 사용
def fibonacci(n):
    if n in dictionary:
        return dictionary[n]
    else: 
        output = fibonacci(n - 1) + fibonacci(n - 2)
        dictionary[n] = output
        return output

들여 쓰기가 줄기 때문에 코드를 쉽게 읽을 수 있다.

def fibonacci(n):
    if n in dictionary:
        return dictionary[n]
    output = fibonacci(n - 1) + fibonacci(n - 2)
    dictionary[n] = output
    return output

리스트 평탄화하는 재귀 함수 만들기

리스트 평탄화: 중첩된 리스트가 있을 때 중첩을 모두 제거하고 풀어서 1차원 리스트로 만드는 것을 의미

  • 리스트 평탄화 하기 (1)
def flatten(data):
    output = []
    for item in data :
        if type(item) == list :
            output += item
        else:
            output.append(item)
    return output

example = [[1, 2, 3], [4, [5, 6]], 7, [8, 9]]
print("원본: ", example)
print("변환: ", flatten(example))
#################################################
원본:  [[1, 2, 3], [4, [5, 6]], 7, [8, 9]]
변환:  [1, 2, 3, 4, [5, 6], 7, 8, 9]

리스트를 변환하니 [5, 6] 이라는 리스트가 포함되어 있어 output += item 이라는 코드를 flatten() 함수를 적용해서 output += flatten(item) 으로 변경하면 됩니다.

  • 리스트 평탄화 하기 (2)
def flatten(data):
    output = []
    for item in data :
        if type(item) == list :
            output += flatten(item)
        else:
            output.append(item)
    return output

example = [[1, 2, 3], [4, [5, 6]], 7, [8, 9]]
print("원본: ", example)
print("변환: ", flatten(example))
#################################################
원본:  [[1, 2, 3], [4, [5, 6]], 7, [8, 9]]
변환:  [1, 2, 3, 4, 5, 6, 7, 8, 9]

append(): 함수는 매개변수 하나를 리스트의 마지막 요소로 추가

  • 마지막 요소로 [4, 5, 6] 이 추가된다.
>>> a = [1, 2, 3]
>>> b = [4, 5, 6]
>>> a.append(b)
>>> a
[1, 2, 3, [4, 5, 6]] 

반면 += 연산자 또는 extend() 는 오른쪽에 있는 리스트의 요소를 하나하나 리스트에 추가합니다.

 >>> a = [1, 2, 3]
 >>> b = [4, 5, 6]
 >>> a += b // a.extend(b)
 >>> a
 [1, 2, 3, 4, 5, 6]

꼭 기억해야하는 것

  • 함수의 변수는 함수 호출마다 따로따로 만들어진다.
  • 함수가 끝나면(리턴되면) 함수를 호출했던 위치로 돌아간다.

코드에 이름 붙이기

  • 어떤 설명도 없는 코드
number_input_a = input("숫자 입력> ")
radius = float(number_input_a)

print(2 * 3.14 * radius)
print(3.14 * radius * radius)
  • 주석이 있는 코드
    • 주석으로 코드 내용을 분석하지 않아도 어떤 내용인지 파악
# 숫자 입력을 받습니다.
number_input_a = input("숫자 입력> ")
radius = float(number_input_a)

# 원의 둘레와 넓이를 출력합니다.
print(2 * 3.14 * radius)
print(3.14 * radius * radius)
  • 함수를 활용한 코드
    • 함수 이름으로 어떤 코드인지 유추
    • 코드 본문만 보면 어떤 일이 일어나는지 쉽게 알수 있다.
# 함수의 정의 
def number_input():
	output = input("숫자 입력> ")
    return float(output)
def get_circumference(radius):
	return 2 * 3.14 * radius
def get_circle_area(radius):
	return 3.14 * radius ** 2

# 코드 본문
radius = number_input()
print(get_circumference(radius))
print(get_circle_area(radius))

코드 유지보수

  • 3.14를 숫자로 입력한 상태
def get_circumference(radius)
	return 2 * 3.14 * radius
def get_circle_area(radius):
	return 3.14 * radius ** 2 
  • 3.14를 PI 라는 변수로 설정한 상태
    • 실수가 줄어듬.
    • 가독성이 높아짐.
PI = 3.14

def get_circumference(radius)
	return 2 * PI * radius
def get_circle_area(radius):
	return PI * radius ** 2 
  • 함수를 사용하지 않은 경우
    • <p></p> 태그 대신 <p class='content-line'></p> 로 감싸 달라는 요청 시 일일이 변경해야하고 이에 따른 실수가 발생할 수도 있다.
# 출력합니다.
print("<p>{}</p>".format("안녕하세요."))
print("<p>{}</p>".format("간단한 HTML 태그를 만드는 예입니다."))

#################################################
<p>안녕하세요.</p>
<p>간단한 HTML 태그를 만드는 예입니다.</p>
  • 함수를 사용
# p 태그로 감싸느 ㄴ함수
def p(content):
	# 기존 코드 주석 처리
    # return "<p>{}</p>".format(content)
    # 2022.03.02 - 요청 반영
    return "<p class='content-line'>{}</p>."format(content)

# 출력합니다.
print(p("안녕하세요"))
print(p("간단한 HTML 태그를 만드는 예입니다."))

확인문제

사람 앉히기

  • n 명이 앉았을 때 나머지 사람들도 앉는 경우의 수
  • 💥 다시 체크해 볼것
앉힐수있는최소사람수 = 2
앉힐수있는최대사람수 = 10
전체사람의수 = 100

memo = {}

def 문제(남은사람수, 앉힌사람수):
    key = str([남은사람수, 앉힌사람수])
    # 종료 조건
    if key in memo:
        return memo[key]
    if 남은사람수 < 0:
        return 0 # 무효하니 0을 리턴
    if 남은사람수 == 0:
        return 1 # 유효하니 수를 세면 되서 1을 리턴
    # 재귀 처리
    count = 0
    for i in range(앉힌사람수, 앉힐수있는최대사람수 + 1):
        count += 문제(남은사람수 - i, i)
    # 메모화 처리
    memo[key] = count
    # 종료
    return count

print(문제(전체사람의수, 앉힐수있는최소사람수))

함수 고급

  • 튜플 : 함수와 함께 많이 사용되는 리스트와 비슷한 자료형으로, 리스트와 다른 점은 한번 결정된 요소는 바꿀 수 없습니다.
  • 람다 : 매개변수로 함수를 전달하기 위해 함수 구문을 작성하는 것이 번거롭고, 코드 공간 낭비라는 생각이 들 떄 함수를 간단하고 쉽게 선언하는 방법입니다.

튜플

(데이터, 데이터, 데이터, ...)

  • 함수와 함꼐 많이 사용되는 리스트와 비슷한 자료형
  • 변경 불가능
>>> tuple_test = (10, 20, 30)
>>> tuple_test[0]
10
>>> tuple_test[1]
20
>>> tuple_test[2]
30
  • 변경 시도시 에러 발생
>>> tuple_test[0] = 1
Traceback (most recent call last):
	File "<pyshell#1>", line 1, in <module>
    	tuple_test[0] = 1
TypeError: 'tuple' object does not support item assignment
  • 요소를 하나만 가지는 튜플
    • (273, ) O
    • (273) X

괄호 없는 튜플

  • 리스트와 튜플은 할당 구문으로 사용가능
# 리스트와 튜플의 특이한 사용
[a, b] = [10, 20]
(c, d) = (10, 20)

# 출력합니다.
print("a:", a)
print("b:", b)
print("c:", c)
print("d:", d)
#################################################
a: 10
b: 20
c: 30
d: 40
  • 괄호를 생략해도 튜플로 인식할 수 있는 경우는 괄로를 생략
# 괄호 없는 튜플
tuple_test = 10, 20, 30 ,40
print("# 괄호가 없는 튜플의 값과 자료형 출력")
print("tuple_test:", tuple_test)
print("type(tuple_test):", type(tuple_test))
print()

# 꽐호가 없는 튜플 활용
a, b, c = 10, 20, 30
print("# 괄호가 없는 튜플을 활용한 할당")
print("a:", a)
print("b:", b)
print("c:", c)
#################################################
# 괄호가 없는 튜플의 값과 자료형 출력
tuple_test: (10, 20, 30, 40)
type(tuple_test): <class 'tuple'>

# 괄호가 없는 튜플을 활용한 할당
a: 10
b: 20
c: 30
  • 변수의 값을 교환하는 튜플
    • a, b = b, a 라는 코드 만으로도 ㄱ밧이 바뀝니다.
a, b = 10, 20

print("# 교환 전 값")
print("a:", a)
print("b:", b)
print()

# 값을 교환합니다.
a, b = b, a

print("# 교환 후 값")
print("a:", a)
print("b:", b)
print()

튜플과 함수

  • 튜플은 함수의 리턴에 많이 사용
    • 튜플을 사용하면 여러 개의 값을 리턴 가능
# 함수를 선언합니다. 
def test():
    return (10, 20)

# 여러 개의 값을 리턴 받습니다.
a, b = test()

# 출력합니다.
print("a:", a)
print("b:", b)
#################################################
a: 10
b: 20

람다

  • 함수라는 '기능'을 매개변수로 전달하는 코드를 많이 사용

함수의 매개변수로 함수 전달하기

  • 콜백 함수: 함수의 매개변수에 사용하는 함수
# 매개변수로 받은 함수를 10번 호출하는 함수
def call_10_times(func):
    for i in range(10):
        func()

# 간단한 출력하는 함수
def print_hello():
    print("안녕하세요")

# 조합하기
call_10_times(print_hello)

filter() 함수와 map() 함수

  • 함수를 매개변수로 사용하는 대표적인 표준(내장)함수
  • map() : 리스트의 요소를 함수에 넣고 리턴된 값으로 새로운 리스트를 구성해 주는 함수
    • map(함수, 리스트)
  • filter(): 리스트의 요소를 함수에 넣고 리턴된 값이 True인 것으로, 새로운 리스트를 구성해 주는 함수
    • filter(함수, 리스트)
# 함수를 선언합니다.
def power(item):
    return item * item
def under_3(item):
    return item < 3

# 변수를 선언합니다.
list_input_a = [1, 2, 3, 4, 5]

# map() 함수를 사용합니다.
output_a = map(power, list_input_a)
print("# map() 함수의 실행 결과")
print("map(power, list_input_a):", output_a)
print("map(power, list_input_a):", list(output_a))
print()

# filter() 함수를 사용합니다.
output_b = filter(under_3, list_input_a)
print("# filter() 함수의 실행 결과")
print("filter(under_3, list_input_a):", output_b)
print("filter(under_3, list_input_a):", list(output_b))

#################################################
# map() 함수의 실행 결과
map(power, list_input_a): <map object at 0x0000024A4A187E50>        
map(power, list_input_a): [1, 4, 9, 16, 25]

# filter() 함수의 실행 결과
filter(under_3, list_input_a): <filter object at 0x0000024A4A187DC0>
filter(under_3, list_input_a): [1, 2]
  • map()과 filter() 의 결과로 <map object> 와 <fileter object> 가 나오는데 이것을 제너레이터 라고 부름

람다의 개념

  • 람다: 간단한 함수를 쉽게 선언하는 방법
    lambda 매개변수: 리턴값
# 함수를 선언합니다.
power = lambda x: x * x
under_3 = lambda x: x <3

# 변수를 선언합니다.
list_input_a = [1, 2, 3, 4, 5]

# map() 함수를 사용합니다.
output_a = map(power, list_input_a)

# filter() 함수를 사용합니다.
output_b = filter(under_3, list_input_a)
  • 람다를 변수에 저장하는 것은 어차피 함수를 넣는 것과 같다고 생각할 수 있기 때문에
    사용하는 즉시 바로 사용하도록 map(), filter() 인자에 바로 넣었습니다.
  • 인라인 람다 선언
# 변수를 선언합니다.
list_input_a = [1, 2, 3, 4, 5]

# map() 함수를 사용합니다.
output_a = map(lambda x: x * x, list_input_a)
print("# map() 함수의 실행 결과")
print("map(power, list_input_a):", output_a)
print("map(power, list_input_a):", list(output_a))
print()

# filter() 함수를 사용합니다.
output_b = filter(lambda x: x <3, list_input_a)
print("# filter() 함수의 실행 결과")
print("filter(under_3, list_input_a):", output_b)
print("filter(under_3, list_input_a):", list(output_b))

파일 처리

  • 표준 함수로 기본 제공
  • 파일 : 텍스트 / 바이너리
  • 열기, 읽기, 쓰기

파일 열고 닫기

  • open() : 파일 열기
  • 파일 객체 = open(문자열: 파일 경로, 문자열: 읽기 모드)
  • 첫 번째 매개변수: 파일 경로
  • 두 번쨰 매개변수: 모드
    • 모드설명
      wwrite 모드(새로 쓰기 모드)
      aappend 모드(뒤에 이어서 쓰기 모드)
      rread 모드(읽기 모드)
  • close() : 파일 닫기
    • 💥 open() 으로 열었으면 close() 로 닫는 습관 들이기!

with 키워드

  • with 구문이 종료 될때 자동으포 파일이 close() 됩니다.
  • 파일을 열고 닫지 않는 실수를 줄일 수 있다.
with open(문자열: 파일경로, 문자열: 모드) as 파일 객체: 
	문장

스트림

  • 스트림: 프로그램이 외부 파일, 외부 네트워크 등과 통신할 때 데이터가 흐르는 길
  • open() 함수는 프로그램에서 파일로 흐르는 길을 만드는 것이고, close() 함수를 프로그램에서 파일로 흐르는 길을 닫는 것

텍스트 읽기

  • write() : 파일 쓰기
  • read(): 파일 읽기
    • 파일을 열고 파일 객체의 read() 함수를 호출 하면 내부에 있는 데이터를 모두 읽어 출력
      파일 객체.read()
# 파일을 엽니다.
with open("basic.txt", "r") as file:
    # 파일을 읽고 출력합니다.
    contents = file.read()
print(contents)

#################################################
Hello Python Programming...!

텍스트 한 줄씩 읽기

  • 텍스트를 사용해 데이터를 구조적으로 표현하는 방법: CSV, XML, JSON
  • CSV(Comma Separated Values): 쉼표로 구분된 값들
    • 첫 번째 줄에 헤더를 넣어 각 데이터가 무엇을 나타내는지 설명
이름, 키, 몸무게 -> 헤더
윤인성, 176, 62 -> 데이터
연하진, 169, 50

💦 cf. 머신러닝 등에서 이러한 형태로 수십만 명의 데이터를 저장하고 활용하는 경우가 많은데 , 한번에 모든 데이터를 올려놓고 사용하는 것은 컴퓨터의 성능에 영향을 끼칤수 있으니,
한번에 필요한 양만큼만 잘라서 처리하는 것을 반복하는 것이 좋다.

  • 예 : 랜덤하게 1000명의 키와 몸무게 만들기
# 랜덤한 숫자를 만들기 위해 가져옵니다.
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)
        # 텍스트를 씁니다.
        file.write("{}, {}, {}\n".format(name, weight, height))
  • 데이터 한 줄씩 읽기
for 한 줄을 나타내는 문자열 in 파일 객체:
	처리

반복문으로 파일 한 줄씩 읽기

  • 파일을 처리하는 코드, 파일 처리 관련 기능을 외우기 어렵기 때문에 내 것으로 만드는 정리 과정이 필요하며, 이 후 과거 스스로 정리 했던 코드를 살펴보는 것이 좋다.
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 = 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()

제너레이터

  • 제너레이터: 이터레이터를 직접 만들 때 사용하는 코드, 함수 내부에 yield 키워드 사용시 제너레이터 함수가 되며, 일반 함수와는 달리 함수를 호출해도 함수 내부의 코드가 실행되지 않음.

제너레이터 함수

# 함수를 선언합니다
def test():
    print("함수가 호출되었습니다.")
    yield "test"

# 함수를 호출합니다.
print("A 지점 통과")
test()

print("B 지점 통과")
test()
print(test())

원래 함수가 호출되었다는 문자열이 출력되어야 하지만, 출력되지 않습니다. 리턴으로 <generator object test at 0x02F20C90> 등이 출력됩니다.
제너레이터 함수는 제너레이터를 리턴합니다.

제너레이터 객체는 next() 함수를 사용해 함수 내부의 코드를 실행, 이 때 yield 키워드 부분까지만 실행, next() 함수의 리턴값으로는 yield 키워드 뒤에 입력한 값이 출력

제너레이터 객체와 next() 함수

# 함수를 선언합니다.
def test():
    print("A 지점 통과")
    yield 1 
    print("B 지점 통과")
    yield 2
    print("C 지점 통과")

# 함수를 호출합니다.
output = test()
# next() 함수를 호출합니다.
print("D 지점 통과")
a = next(output)
print(a)
print("E 지점 통과")
b = next(output)
print(b)
print("F 지점 통과")
c = next(output)
print(c)
# 한 번 더 실행하기
next(output)

#################################################
D 지점 통과
A 지점 통과
1
E 지점 통과
B 지점 통과
2
F 지점 통과
C 지점 통과
Traceback (most recent call last):
  File "generator01.py", line 19, in <module>
    c = next(output)
StopIteration
  • next() 함수를 호출한 이후 yield 키워드를 만나지 못하고 함수가 끝나면 StopIteration이라는 예외가 발생

  • 제너레이터 객체는 함수의 코드를 조금씩 실행할 때 사용

리스트 함수와 key 키워드 매개변수

profile
끄적끄적 쓰는곳

0개의 댓글