1. 재귀함수

1) 팩토리얼  factorial

 n ! = n * (n-1) * (n-2) * ... * 1

 

 👾  이러한 팩토리얼을 구하는 방법은 2가지로 구분

       a. 반복문 사용

       b. 재귀 함수 사용

 

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

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))
'''
1!: 1
2!: 2
3!: 6
4!: 24
'''

 

 

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

   - 재귀 recursion 란 '자기 자신을 호출하는 것'을 의미

f(4) = 4 * f(3)
     = 4 * 3 * f(2)
     = 4 * 3 * 2 * f(1) * f(0)
     = 4 * 3 * 2 * 1 * 1
def factorial(n):
    if n == 0:
        return 1
    else:
        return n * factorial(n-1)
        
print("1!:", factorial(1))
print("2!:", factorial(2))
print("3!:", factorial(3))
print("4!:", factorial(4))

 


 

2. 피보나치 수열  Fibonacci numbers

 

👩🏻‍💻  피보나치 수를 처음 연구한 것은 레오나르도 피오나치로 토끼 수의 증가에 대해서 이야기하면서 이 수에 대해 언급했다 

   

  📌  n 번째 달의 토끼 수

  • 첫 달에는 새로 태어난 토끼 한 쌍만이 존재한다.
  • 두 달 이상이 된 토끼는 번식 가능하다.
  • 번식 가능한 토끼 한 쌍은 매달 새끼 한 쌍을 낳는다.
  • 토끼는 죽지 않는다.

출처 : commons.wikimedia.org

 

 

    📌  1번째 수열 = 1

           2번째 수열 = 1

           n번째 수열 = (n-1)번째 수열 + (n-2)번째 수열

 

def fibonacci(n):
    if n == 1:
        return 1
    if n == 2:
        return 1
    else:
        return fibonacci(n-1) + fibonacci(n-2)
        
print("fibonnaci(1):", fibonacci(1))
print("fibonnaci(2):", fibonacci(2))
print("fibonnaci(3):", fibonacci(3))
print("fibonnaci(4):", fibonacci(4))
'''
fibonnaci(1): 1
fibonnaci(2): 1
fibonnaci(3): 2
fibonnaci(4): 3
'''

 

count = 0

def fibonacci(n):
    print("fibonacci({})를 구합니다.".format(n))
    global count
    count += 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(count))
 '''
fibonacci(10)를 구합니다.
fibonacci(9)를 구합니다.
...생략...
fibonacci(1)를 구합니다.
fibonacci(2)를 구합니다.
---
fibonacci(10) 계산에 활용된 덧셈 횟수는 109번입니다.
'''

 

💡  위와 같이 덧셈 횟수가 기하급수적으로 늘어나는 이유

 

 

 👾  다음과 같은 형태의 그림을 트리 tree 라고 한다.

 👾  트리에 있는 각각의 지점을 노드 node, 마지막 단계의 노드를 리프 leaf 

     ➡️  트리 내부에 있는 각각의 노드 값을 계산하려면 덧셈을 한 번씩 해야 함

      ➡️  한 번 구한 값은 그것으로 계산이 끝나는 게 아니라,

            한 번 구했던 값이라도 처음부터 다시 계산해야 함

      ➡️  이 때문에 계산 횟수가 기하급수적으로 늘어나는 것

 

 


 

💡 위의 예제에서 global count를 쓰는 이유

   

    - 파이썬은 함수 내부에서 함수 외부에 있는 변수를 참조하지 못한다.

    - 함수 내부에서 함수 외부에 있는 변수라는 것을 설명하려면 다음과 같은 구문을 사용해야 UnboundLocalError가 발생하지 않는다.

global 변수 이름

 


 

3. 메모화

👩🏻‍💻  한 번 계산한 값을 저장해 놓은 후, 이후에 다시 계산하지 않고 저장된 값을 활용하는 기술

# 메모 변수 생성
dic = {
    1: 1,
    2: 1
}

def fibonacci(n):
    if n in dic:
        # 메모가 되어 있으면 메모된 값을 리턴
        return dic[n]
    else:
        # 메모가 되어 있지 않으면 값을 구함
        output = fibonacci(n-1) + fibonacci(n-2)
        dic[n] = output
        return output
# 함수 호출        
print("fibonnaci(10):", fibonacci(10))
print("fibonnaci(20):", fibonacci(20))
print("fibonnaci(30):", fibonacci(30))
print("fibonnaci(40):", fibonacci(40))

 

 

👾  딕셔너리를 사용해서 한 번 계산한 값을 저장, 이를 메모한다고 표현

👾  딕셔너리에 값이 메모되어 있으면 처리를 수행하지 않고 곧바로 메모된 값을 돌려주면서 코드 속도를 빠르게 만든다.

 


 

4. 리스트 평탄화

👩🏻‍💻  중첩된 리스트가 있을 때 중첩을 모두 제거하고 풀어서 1차원 리스트로 만드는 것을 의미

 

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(flatten(example))
 # [1, 2, 3, 4, 5, 6, 7, 8, 9]

 

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

         ➡️ append(리스트_자료형) 형태로 리스트를 전달하면 리스트 전체가 하나의 요소로서 추가됨

  ⚡️  += 연산자는 오른쪽에 있는 '리스트의 요소'를 하나하나 리스트에 추가

 

 

 

 

 

[ 내용 참고 : 책 '혼자 공부하는 파이썬']


 

1. 함수란 ?

🚀  '코드의 집합'을 의미 def 키워드 사용함

🚀   함수 용어 정리
        a. 인수 : 함수에 전달할 입력(input)을 의미. argument
        b. 매개변수 : 인수를 받아서 저장하는 변수를 의미. parameter
        c. 반환값 : 함수의 출력(output)을 의미. return
        d. 함수 호출 : 만들어진 함수를 실제로 사용하는 것을 의미

def 함수이름(매개변수):
    본문
    return 반환값
    
# 함수이름을 개발자가 마음대로 결정가능
# 매개변수, 반환값은 필수 사항이 아님

# 함수 호출
변수 = 함수이름(인수)
# 함수의 호출 결과를 저장할 변수를 생략 가능

 

  ⚡️  4가지 함수 호출 형태


       1) 인수: x, 반환값: x
           함수이름()
       2) 인수: o, 반환값: x
           함수이름(인수)
       3) 인수: x, 반환값: o
           변수 = 함수이름()
       4) 인수: o, 반환값: o
           변수 = 함수이름(인수)


# welcome() 함수 정의
def welcome():
    print('Hello Python')
    print('Nice to meet you')

welcome()  # 함수가 정의된 후에 호출을 해야 함
# Hello Python
# Nice to meet you

# 파이썬 함수의 단점 : 데이터 타입이 없어서 다른 작업자가 만든 함수를 사용할 때 주의할 점이 많다.
def process(number):
    return number / 1

process("hello")  # TypeError: unsupported operand type(s) for /: 'str' and 'int'

# 어노테이션 사용 가능. 타입 강제는 아님
def process(number: int) -> float:
    return number / 1

# 파이썬의 함수는 객체이고 자료형이다.
def charge(energy):
    if energy < 0:
        print('0보다 작은 에너지를 충전할 수 없습니다.')
        return  
    print('에너지가 충전되었습니다.')
    
print(charge)  
# <function charge at 0x10360dcf0>

def print_charge(fun):
    fun(0)  # 에너지가 충전되었습니다.

print_charge(charge)  # 함수를 함수 호출시 인수로 사용이 가능.

# 함수안에 함수 선언도 가능하다.
def print_greet(name):
    def get_greet():
        return '안녕하세요'

    print(name + "님 " + get_greet())

print_greet('김철수')

 

2. 인수와 매개변수

 

1) 인수가 있는 함수

def introduce(name: str, age: int) -> None:
    print(f'내 이름은 {name}이고, 나이는 {age}살 입니다.')

introduce('james', 25)  # 내 이름은 james이고, 나이는 25살 입니다.
introduce(age=25, name='james')  # 내 이름은 james이고, 나이는 25살 입니다.

 


 

2) 가변 매개변수

🚀  함수로 전달해야 하는 인수의 개수가 정해지지 않아도 매개변수를 선언할 수 있음
🚀  가변 매개변수를 만드는 키워드는 애스터리스크(*)
🚀  매개변수 앞에 *를 붙이면 곧바로 가변 매개 변수가 되면서 전달되는 모든 인수를 하나의 튜플(tuple)로 만들어 줌

def show(*args):
    for item in args:
        print(item)

show('python')  # show 함수 호출. 인수가 1개
show('happy', 'birthday')  # show 함수 호출. 인수가 2개

def print_n(n, *values):
    for i in range(n):
        for value in values:
            print(value)
        print()
print_n(3, "안녕하세요", "파이썬 프로그래밍")
'''
안녕하세요
파이썬 프로그래밍

안녕하세요
파이썬 프로그래밍

안녕하세요
파이썬 프로그래밍
'''

 

  👾  가변 매개변수 뒤에 일반 매개변수 올 수 x

  👾  가변 매개변수는 하나만 사용 가능

 


 

3) 기본 매개변수

 

print(value, sep=' ', end='\n', file=sys.stdout)

 

🚀  가장 앞에 있는 value가 '가변 매개변수', 뒤에 '매개변수 = 값' 형태로 되어 있는 것이 '기본 매개변수'

🚀  매개변수를 입력하지 않았을 경우 매개변수에 들어가는 기본값을 말한다

🚀  기본 매개변수 뒤에 일반 매개변수가 올 수 없다

 

    ⚡️  end : value 출력 후 출력할 문자
                       ▶️ end 속성을 사용하지 않고 print() 함수를 사용하면 출력 후 자동으로 줄 바꿈이 진행
    ⚡️  sep : 출력할 value의 구분자
                       ▶️ sep 속성을 사용하지 않고 print() 함수를 사용하면 출력 대상은 공백으로 구분
    ⚡️  file : 출력 방향 지정
                       ▶️ file 속성을 사용하지 않고 print() 함수를 사용하면 출력 대상은 모니터에 출력

print('재미있는','파이썬') # sep 값을 지정하지 않으면 공백이 들어감.
print('재미있는', '파이썬', sep=' ') # 재미있는 파이썬 / 콤마(,)로 구분된 출력 대상은 공백으로 구분
print('Python','Java', 'C', sep=':') #Python:Java:C / sep 속성으로 구분
'''
재미있는 파이썬
재미있는 파이썬
Python:Java:C
'''

print('영화 타이타닉', end='\n') # 지정하지 않았을 때 기본값은 \n
print('평점', end=':')
print('5점') # 평점:5점 / value 출력 후 end 속성 출력. 줄 바꿈이 되지 않음
'''
영화 타이타닉
평점:5점
'''

fos = open('../02_21/sample.py', mode='wt')
print('print("Hello World")', file = fos) # file 속성으로 대상 출력. 파일 출력
fos.close()

 


 

4) 키워드 매개변수

 A. 기본 매개변수가 가변 매개변수보다 앞에 오는 경우

     - 기본 매개변수의 의미가 사라진다.

def print_n(n=2, *values):
    for i in range(2):
        for value in values:
            print(value)
            
print_n('안녕하세요','즐거운','파이썬 프로그래밍')
# TypeError 발생

 

    📌  n에는 안녕하세요가 들어가고, values에 즐거운, 파이썬 프로그래밍이 들어간다

    📌  range() 함수의 매개변수에는 숫자만 가능하기 때문에 에러가 발생

           ∴  기본 매개변수는 가변 매개변수 앞에 써도 의미가 없다.

 

 

  B. 가변 매개변수가 기본 매개변수보다 앞에 오는 경우

def print_n(*values, n=2):
    for i in range(2):
        for value in values:
            print(value)
            
print_n('안녕하세요','즐거운','파이썬 프로그래밍', 3)

 

 

📌  가변 매개변수가 우선이 되기 때문에 왼쪽과 같은 결과가 나온다.

 

 

 

 

 

 

  C. 키워드 매개변수

     - 매개변수 이름을 지정해서 입력하는 매개변수를 키워드 매개변수라고 한다

def print_n(*values, n=2):
    for i in range(2):
        for value in values:
            print(value)
            
print_n('안녕하세요','즐거운','파이썬 프로그래밍', n=3)
# n=3은 키워드 매개변수

 


 

5) 디폴트 매개변수

🚀  매개변수로 전달되는 인수가 없는 경우에 기본적으로 사용할 수 있도록 매개변수에 기본값을 설정할 수 있음

def greet(message='안녕하세요'):
    print(message)

greet('반갑습니다')  # 반갑습니다
greet()  # 안녕하세요
# -> 자바에서는 오버로딩이라 생각함. 파이썬에는 오버로딩 지원 x.

# 디폴트 매개변수와 일반 매개변수를 같이 사용하는 경우 디폴트 매개변수를 뒤(오른쪽)으로 배치
def greet(name, message= '안녕하세요'):
    print(f'{name}님 {message}')

greet('김철수')  # 김철수님 안녕하세요.
greet('김철수', '반갑습니다')  # 김철수님 반갑습니다

# 복수의 디폴트 매개변수를 사용하는 경우
def greet(name='이철수', message='안녕하세요'):
    print(f'{name}님 {message}.')

greet()  # 이철수님 안녕하세요.
greet('김철수')  # 김철수님 안녕하세요. / 왼쪽 부터 적용.
greet('김철수', '반갑습니다')  # 김철수님 반갑습니다.

 


 

3. 리턴

🚀  함수 호출 결과를 반환값(return value)이라 한다.
🚀  반환값이 있으면 함수 내부에서 return문을 통해 값을 반환할 수 있고,
      반환값이 없으면 함수 내부에 return문을 작성할 필요가 없음

def address():
    string = '우편번호 12345\n'
    string += '서울시 영등포구 여의도동'
    return string

print(address())
''' 
실행결과)
우편번호 12345
서울시 영등포구 여의도동
'''

def address():
    string = '우편번호 12345\n'
    string += '서울시 영등포구 여의도동'
    print(string)

print(address())  # None : 반환값이 없어서 출력이 안됨

 


 

1)  다중 반환

  👾  하나의 반환값도 처리할 수 있고 여러 개의 반환값도 처리할 수 있음

def calculator(*args):
    return sum(args), sum(args) / len(args), max(args), min(args)

a, b, c, d = calculator(1, 2, 3, 4, 5)  # 4개의 반환값을 모두 저장하기 위해서 변수 4개 배치
print('합계', a)  # 합계 15
print('평균', b)  # 평균 3.0
print('최댓값', c)  # 최댓값 5
print('최솟값', d)  # 최솟값 1

# result는 4개의 반환값을 저장하는 튜플.
result = calculator(1, 2, 3, 4, 5)
print('합계', result[0])  # 합계 15
print('평균', result[1])  # 평균 3.0
print('최댓값', result[2])  # 최댓값 5
print('최솟값', result[3])  # 최솟값 1

 



2) 함수의 종료를 위한 return

  - 반환값이 있으면 return문을 사용해 반환하고, 반환값이 없으면 return문을 생략하면 됨

def charge(energy):
    if energy < 0:
        print('0보다 작은 에너지를 충전할 수 없습니다.')
        return  # charge() 함수의 종료를 의미.
    print('에너지가 충전되었습니다.')

charge(1)   # 에너지가 충전되었습니다.
charge(-1)  # 0보다 작은 에너지를 충전할 수 없습니다.

 



 

 

 

 

[ 내용 참고 : IT 학원 강의 자료 및 책 '혼자 공부하는 파이썬' ]

 


 

1. 내장 함수란?

👾  파이썬 인터프리터에는 항상 사용할 수 있는 많은 함수가 내장되어 있으며, 이를 내장 함수 built-in function 이라고 함
👾  외부에 따로 저장해 둔 모듈에서 불러오는 것이 아니기 때문에 import가 필요 없음

 


 

2. 문자 내장 함수

chr() 특정 문자의 유니코드 값을 전달하면 해당 유니코드 값을 가진 문자를 반환하는 함수
  ▶️ 유니코드의 유효범위 0 ~ 1,114,111 / 아스키코드의 유효 범위 0 ~ 127
ord() 문자를 전달하면 해당 문자의 유니코드 값을 반환
eval() 실행하고자 하는 표현식(expression) 을 문자열로 전달하면 표현식의 결과값을 반환
format() 전달받은 인수와 포맷 코드에 따라 형식을 갖춘 문자열을 반환
   ▶️ 포맷 코드를 전달하지 않으면 str()을 호출한 것과 같음
str() 전달받은 인수를 문자열로 변환하여 반환
# chr()
print(chr(48))  # 0
print(chr(49))  # 1
print(chr(65))  # A
print(chr(66))  # B
print(chr(97))  # a
print(chr(98))  # b

# ord()
print(ord('A'))  # 65
print(ord('한'))  # 54620

# eval()
print(eval('100 + 200'))  # 300
a = 10
print(eval('a * 5'))  # 50
print(eval('min(1, 2, 3)'))  # 1

# format()
print()
print(format(10000))  # 10000 / str(10000)과 같음
print(format(10000, '_'))  # 10_000 / 천단위 구분 기호로 밑줄(_)을 사용
print(format(10000, ','))  # 10,000 / 천단위 구분 기호로 쉼표(,)를 사용

 


 

3. 숫자 내장 함수

abs() 전달된 인수 (정수 혹은 실수)의 절대값을 반환
divmod() 전달된 두 인수를 나누어 몫과 나머지를 한 쌍의 결과로 반환. 몫과 나머지는 하나의 튜플(tuple)로 반환
float() 전달된 인수(숫자 또는 문자열)를 실수로 만들어 반환. 전달된 인수가 없는 경우에는 0.0을 반환
int () 전달된 인수(숫자 또는 문자열)를 정수로 만들어 반환. 전달된 인수가 없는 경우에는 0을 반환
max() 전달된 인수 중 가장 큰 값을 반환
min() 전달된 인수 중 가장 작은 값을 반환
pow() 전달된 두 인수의 거듭제곱을 반환. 연산자 중에서 거듭 제곱 연산자 ** 와 같음
round()  전달된 인수를 이용해 반올림한 값을 반환
  ▶️ 전달된 인수가 하나이면 정수로 반올림한 값을 반환
  ▶️ 전달된 인수가 2개이면 두 번째로 전달한 인수만큼 소수점을 남겨둠
sum()  전달된 리스트나 튜플과 같은 반복가능객체의 합계를 반환
  ▶️ 숫자가 아닌 값을 전달하면 에러가 발생
# abs()
print(abs(10))  # 10
print(abs(-10))  # 10

# divmod()
print(divmod(10, 3))  # (3, 1)
print(type(divmod(10, 3)))  # <class 'tuple'>

# max()
print(max(1,10))  # 10
li = [5, 3, 4, 2, 1]
print(max(li))  # 5

# min()
print(min(1,10))  # 1
li = [5, 3, 4, 2, 1]
print(min(li))  # 1

# pow()
print(pow(10, 2))  # 100
print(pow(10, 3))  # 1000
print(pow(10, -2))  # 0.01
print(pow(10, -3))  # 0.001

# round()
print(round(1.5))  # 2
print(round(1.4))  # 1
print(round(1.55, 1))  # 1.6
print(round(2.675, 2))  # 2.67 -> 부동 소수점 에러로 인해 2.68이 아니라 2.67이 반환
print(round(2.6755, 2))  # 2.68

# sum() 
list1 = [1, 2, 3, 4, 5]
print(sum(list1))  # 15

list2 = ['h', 'e', 'l', 'l', 'o']
# print(sum(list2))

 


 

3. 시퀀스 내장 함수

enumerate() 리스트에 저장된 요소와 해당 요소의 인덱스가 튜플 tuple 형태로 함께 추출
range() 전달된 인수값에 따라 시퀀스 자료형의 데이터를 생성
  1) range(stop) : 0부터 stop 사이의 모든 정수
  2) range(start, stop) : start부터 stop 사이의 모든 정수
  3) range(start, stop, step) : start부터 stop 사이의 정수 중에서 step만큼의 차이를 가지고 있는 정수
len() 함수에 전달된 객체의 길이(항목 수)를 반환
sorted() 전달된 반복가능객체의 오름차순 정렬 결과를 반환
reverse=True 옵션을 추가할 경우 내림차순 정렬 결과를 반환
zip() 전달된 여러 개의 반복가능객체의 각 요소를 튜플로 묶어서 반환
전달된 반복가능객체들의 길이가 서로 다르면 길이가 짧은 반복가능객체 기준으로 동작
reversed() 리스트에서 요소의 순서를 뒤집어서 반환
 ▶️ 리턴 값 'reverseiterator' : 요소 하나하나 꺼내기 위해 next() 함수 사용해야 함
items() 딕셔너리에서 items() 함수를 사용하면 키와 값을 조합해서 반복문 작성
# 1. enumerate()
# for item in enumerate([리스트]) :
#   반복실행문

for item in enumerate(['가위', '바위', '보']):
    print(item)
    
# (0, '가위')
# (1, '바위')
# (2, '보')

for idx, element in enumerate(['가위', '바위', '보']):
    print(idx, ' / ', element)
# 0  /  가위
# 1  /  바위
# 2  /  보

# 2. range()

print(list(range(10))) # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
print(list(range(1, 11))) # [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
print(list(range(0, 30, 5))) # [0, 5, 10, 15, 20, 25]
print(list(range(0, -10, -1))) # [0, -1, -2, -3, -4, -5, -6, -7, -8, -9]
print(list(range(0))) # []

# 3. len()
li = ['a', 'b', 'c', 'd']
print(len(li))  # 4

d = {'a': 'apple', 'b': 'banana'}
print(len(d))  # 2 / 딕셔너리는 '키:값'으로 구성된 한 쌍을 하나의 데이터로 봄

print(len(range(10)))  # 10 / range() 함수로 생성되는 값은 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
print(len(range(1, 10)))  # 9 / range() 함수로 생성되는 값은 1, 2, 3, 4, 5, 6, 7, 8, 9

# range() 함수와 리스트의 길이를 구하는 len() 함수를 함께 사용하면 리스트의 인덱스를 생성 가능
seasons = ['봄', '여름', '가을', '겨울']
seasons_eng = ['spring', 'summer', 'fall', 'winter']
for idx in range(len(seasons)):
    print(f'{seasons[idx]} / {seasons_eng[idx]}')

# 4. sorted() 
my_list2 = ['b', 'c', 'a', 'd']
print(sorted(my_list2))  # ['a', 'b', 'c', 'd']
print(sorted(my_list2, reverse=True))  # ['d', 'c', 'b', 'a']

print(sorted(my_list))  # [1, 2, 3, 4, 5, 6]
print(my_list)  # [6, 3, 1, 2, 5, 4] / 실제로 정렬이 된건 아님

my_list = sorted(my_list)  # 오름차순 정렬 결과를 덮어쓰기
print(my_list)  # [1, 2, 3, 4, 5, 6]

# 5. zip() 
names = ['james', 'emily', 'amanda']
scores = [60, 70, 80]
for student in zip(names, scores):
    print(student)
# ('james', 60)
# ('emily', 70)
# ('amanda', 80)

# 튜플은 언패킹이 가능하므로 다음과 같은 모습으로 구성 가능
for name, score in zip(names, scores):
    print(f'{name}의 점수는 {score}입니다.')
# james의 점수는 60입니다.
# emily의 점수는 70입니다.
# amanda의 점수는 80입니다.

for idx, name in enumerate(names):
    print(f'{name}의 점수는 {scores[idx]}입니다.')

for idx in range(len(names)):
    print(f'{names[idx]}의 점수는 {scores[idx]}입니다.')
  
6. reversed()
list_a = [1, 2, 3, 4, 5]
print(list(reversed(list_a)))
# [5, 4, 3, 2, 1]

# 7. items()
dic_ex = {
    'james': 60,
    'emily': 70,
    'amanda': 80
}
print(dic_ex.items())
# dict_items([('james', 60), ('emily', 70), ('amanda', 80)])

 


 

⚡️ 월과 일수 조합해서 반환하는 문제

months_eng = ['January', 'February', 'March', 'April', 'May', 'June', 'July',
              'August', 'September', 'October', 'November', 'December']
months = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]

# 1. range() 사용
for idx in range(len(months)):
    print(f'{months_eng[idx]} = {months[idx]}일')

# 2. enumerate() 사용
for i, v in enumerate(months_eng):
    print(f'{v} = {months[i]}일')

print()

# 3. dict 사용
months_dic = dict()
for i, v in enumerate(months_eng):
    months_dic.update({v: months[i]})

for k, v in months_dic.items():
    print(f'{k} = {v}일')

# 4. zip() 사용
for item1, item2 in zip(months_eng), months:
    print(f'{item1} = {item2}일')

 


 

4. 리스트 내포  list comprehensions

 

리스트 이름 = [표현식 for 반복자 in 반복할 수 있는 것]
리스트 이름 = [표현식 for 반복자 in 반복할 수 있는 것 if 조건문]
# 예시 1.
array = [i*i for i in range(0, 20, 2)]
print(array)
# [0, 4, 16, 36, 64, 100, 144, 196, 256, 324]

# 예시 2.
array = ['사과', '자두', '바나나', '체리']
output = [fruit for fruit in array if fruit != '체리']
print(output)
# ['사과', '자두', '바나나']

 


 

💡  이터레이터 iterator ?

for 반복자 in 반복할 수 있는 것

 

    -  반복할 수 있는 것을 프로그래밍 용어로 이터러블 iterable 이라고 함

         ➡️ 즉, 내부에 있는 요소들을 차례차례 꺼낼 수 있는 객체를 의미

    -  리스트, 딕셔너리, 문자열, 튜플 등 

    -  이 중에서 next() 함수를 적용해 하나하나 꺼낼 수 있는 요소를 이터레이터 iterator 라고 함

numbers = [ 1, 2, 3, 4, 5]
num = reversed(numbers)

print("num : ", num)
print(next(num))
print(next(num))
print(next(num))
print(next(num))
print(next(num))

#5
#4
#3
#2
#1

 

 

 

 

 

 

[ 내용 참고 : IT 학원 강의 및 책 '혼자 공부하는 파이썬' ]

 


 

1. while 반복문


🚀  do while문이 없음
🚀  특정 조건을 만족하는 동안 반복해서 수행해야 하는 코드를 작성할 때 사용

while 조건식 :
    반복실행문

 

# while 반복문 사용
n = 1
while n <= 10:
    print(n)
    n += 1   # n = n + 1
print(n)

# 1부터 10 사이의 모든 정수를 역순으로 출력
n = 10
while n >= 1:
    print(n)
    n -= 1  # n = n - 1


# 100부터 50 사이의 짝수를 출력
n = 100
while n >= 50:
    if n % 2 == 0:
        print(n)
    n -= 1

n = 100
while n >= 50:
    print(n)
    n -= 2

 


1) 리스트 사용한 while 반복문

'''
사용자로부터 임의의 정수를 입력받아 모두 리스트에 보관.
단 사용자가 0을 입력하면 프로그램을 종료. 이 때 입력받은 0은 리스트에 보관하지 않음.
'''

my_list = []  # 빈 리스트 생성

# 방법 1)
n = int(input('정수를 입력하세요(종료는 0입니다.) >>> '))  # 한 번만 실행

while n != 0:  # n이 0이 아니면 계속 실행
    my_list.append(n)
    n = int(input('정수를 입력하세요(종료는 0입니다.) >>> '))

print(my_list)
print()

# 방법 2)
n = 1  # 0이 아닌 초깃값을 주면 반복문이 실행됩니다.

while n != 0:
    n = int(input('정수를 입력하세요(종료는 0입니다.) >>> '))
    my_list.append(n)

my_list.pop()  # my_list의 마지막 요소는 언제나 0이므로 제거합니다.
print(my_list)

 


 

2) 시간을 기반으로 반복 

🚀  유닉스 타임 Unix Time : 세계 표준시로 1970년 1월 1일 0시 0분 0초를 기준으로 몇 초가 지났는지를 정수로 나타낸 것 

# 유닉스 타임 구하는 법
import time
time.time()
# 시간 모듈
import time

# 변수 선언
number = 0

# 5초 동안 반복
target = time.time() + 5
while time.time() < target:
    number += 1
    
# 출력
print("5초 동안 {}번 반복했습니다.".format(number))
# 5초 동안 65488529번 반복했습니다.

 


 

2. break/continue 키워드

 

👩🏻‍💻  break문 : while문이나 for문과 같은 반복문을 강제로 종료하고자 할 때 사용하는 제어문
                         반복문 내에 break문이 나타나면 곧바로 break문이 포함된 반복문은 종료

n = 1
while True:
    print(n)
    if n == 10:
        break  # if문에서 break문을 작성 했지만 실제로 종료되는 것은 while문
    n += 1
print(n)  # 10

while True:  # 무한 루프
    city = input('대한민국의 수도는 어디인가요? >>> ')
    city = city.strip()  # 문자열의 양쪽끝에서 공백을 없앰
    if city == '서울' or city == 'seoul' or city == 'SEOUL':  # 대소문자 모두 정답처리
        print('정답입니다.')
        break  # 정답을 맞춰야 종료
    else:
        print('오답입니다. 다시 시도하세요.')


# 종료 조건이 2가지인 경우 : 5개까지 입력이 가능 혹은 그전에 그만두려면 q 입력

hobbies = []  # 빈 리스트 생성
while True:  # 무한루프
    hobby = input('취미를 입력하세요(종료는 그냥 q) >> ')
    if hobby == 'q':
        print('입력된 취미가 모두 저장되었습니다.')
        break
    else:
        hobbies.append(hobby)

    if len(hobbies) >= 5:
        print('5개 입력!')
        break
print(hobbies) # 전체 요소 출력

 


 

👩🏻‍💻  continue 문반복문의 시작 지점으로 제어의 흐름을 옮기는 역할
                                 반복에서 제외하거나 생략하고 싶은 코드가 존재할 때 사용

# 1에서 100사이의 모든 정수를 합하는데 3의 배수는 제외
total = 0
for a in range(1,101):
    if a % 3 == 0:  # 3의 배수인지 검사합니다.
        continue
    total += a
print(total)  # 3367


# 과일 이름 5개를 fruits 리스트에 저장.
# 2개는 미리 저장됨.
# 중복된 과일 이름은 저장이 안됨.

fruits = ['사과', '감귤']
count = 3  # 입력가능한 횟수

while count > 0:
    fruit = input('어떤 과일을 저장할까요? >>> ')

    if fruit in fruits:  # fruits 리스트에 fruit 변수에 있는 값이 있다면
        print('동일한 과일이 있습니다.')
        continue  # while문의 시작 지점으로 돌아가서 다시 과일 이름을 입력

    fruits.append(fruit)  # 입력된 과일 이름을 리스트에 저장
    count -= 1  # 입력 가능 횟수가 줄어듦.
    print(f'입력이 {count}번 남았습니다.')

print(f'5개 과일은 {fruits}입니다.')

 

 

 

 

 

[ 내용 참고 : IT 학원 강의 자료 및 책 '혼자 공부하는 파이썬' ]


 

1. 범위  range

 

👾  특정한 횟수만큼 반복해서 돌리고 싶을 때 for 반복문과 범위를 조합해서 사용한다.

👾  정수 범위를 만들어 낼 때 유용한 함수 

# 기본구조
range(초깃값, 종료값, 증감값)

 

  ⚡️  특징   1. 초깃값부터 종료값 전까지 숫자(n)들의 컬렉션을 만듦 (초깃값 <= n < 종료값)
                   2. 초깃값을 생략하면 0부터 시작
                   3. 종료값은 생략할 수 없음
                   4. 증감값을 생략하면 1씩 증가

# 종료값만 존재
range(5) : 0, 1, 2, 3, 4
# 초깃값, 종료값만 존재
range(1, 11) : 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
# 초깃값, 종료값, 증감값 다 존재
range(1, 10, 2) : 1, 3, 5, 7, 9

# 리스트와 튜플
print(list(range(1, 6)))  # [1, 2, 3, 4, 5]
print(tuple(range(1, 6)))  # (1, 2, 3, 4, 5)

 


🚀  수식에 연산자를 사용한 경우

 

  - range() 함수의 매개변수로 반드시 '정수'를 입력해야 함

n = 10
a = range(0, n/2)
# -> 매개변수로 나눗셈을 사용한 경우 'TypeError'발생
a = range(0, n//2)
# -> 몫은 정수로 나오기 때문에 가능

 


 

2.  for 반복문: 범위와 함께 사용

# 기본 형식
for 숫자 변수 in 범위:
    코드
# for 반복문
for n in [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]:
    print(n)

# range() 사용한 for 반복문
for n in range(1, 11):
    print(n)

# range() 함수를 이용해 생성한 값을 사용하지 않는 경우
for n in range(10):  # 10번 반복
    print('Hello')

 


 

🚀  리스트와 범위 조합

# 리스트 선언
array = [270, 33, 100, 55, 11]

# 반복문에 적용
for i in range(len(array)):
    print("{}번째 반복: {}".format(i, array[i])

'''
실행결과)
0번째 반복: 270
1번째 반복: 33
2번째 반복: 100
3번째 반복: 55
4번째 반복: 11
'''

 


 

3. for 반복문: 반대로 반복하기

 

1) range() 함수 매개변수 사용

for i in range(4, 0-1, -1):
    print("현재 반복 변수: {}".format(i))

'''
실행결과)
현재 반복 변수: 4
현재 반복 변수: 3
현재 반복 변수: 2
현재 반복 변수: 1
현재 반복 변수: 0
'''

 

 

2) reversed() 함수 사용

for i in reversed(range(5)):
    print("현재 반복 변수: {}".format(i))
    
'''
실행결과)
현재 반복 변수: 4
현재 반복 변수: 3
현재 반복 변수: 2
현재 반복 변수: 1
현재 반복 변수: 0
'''

 


 

4. 중첩 반복문

output = ""

for i in range(1,10):
    for j in range(0,i):
        output += "*"
    output += "\n"
    
print(output)

 

 

 

  ⚡️  외부의 반복문: 줄생성(\n)

  ⚡️  내부의 반복문: 별생성(*)

 

 

 

 

 

 

 

output = ""

for i in range(1, 10):
    for j in range(9, i, -1):
        output += ' '
    for k in range(0, 2*i-1):
        output += '*'
    output += '\n'
   
print(output)

 

 

 

  ⚡️  외부의 반복문: 줄생성(\n)

  ⚡️  내부의 반복문 1 : 공백생성

 ⚡️  내부의 반복문 2 : 별생성(*)

 

 

 

 

 

 

 

 

 

[ 내용참고 : IT 학원 강의 자료 및  책 '혼자 공부하는 파이썬' ]


 

1. 딕셔너리  dictionary

 

👾  키 key 를 기반으로 값 value을 저장하는 것

       ➡️  '단어'와 '단어의 의미'처럼 사용

👾  딕셔너리는 인덱스가 존재하지 않는 대신 키를 인덱스처럼 사용
       ➡️  키 값을 알면 저장된 값을 확인할 수 있는 구조

 


 

1) 딕셔너리 선언

  ⚡️ 딕셔너리는 중괄호 {} 로 선언하며, 키:값 형태를 쉼표로 연결해서 만든다.

  ⚡️ 키는 문자열, 숫자, 불 등으로 선언 가능

# 딕셔너리 선언 방법
변수 = {
    키:값,
    키:값,
    ...
    키:값
}

# 키값의 자료형이 문자열(str) 이라면 dict() 함수를 이용해서 생성 가능
d = dict(a='apple', b='banana')
print(d)  # {'a': 'apple', 'b': 'banana'}

 

 

💡 딕셔너리 문자열 키와 관련된 오류

    - 키를 문자열로 사용할 때 따옴표를 붙이지 않으면 NameError가 발생한다

dict_key = {
    name : "망고",
    type : "절임"
}
# 이렇게 실행하면 NameError가 발생
# key에 따옴표("")를 붙여줘야 한다

 

2) 딕셔너리 요소 접근

  ⚡️ 리스트처럼 딕셔너리 뒤에 대괄호 []를 입력하고 내부에 인덱스처럼 키를 입력

  ⚡️ 주의할 점은 딕셔너리 선언할 때는 중괄호 {} 사용하지만, 요소에 접근할 때는 대괄호[] 사용

d = {'a': 'apple', 'b': 'banana'}
print(d)  # {'a': 'apple', 'b': 'banana'}
print(type(d))  # <class 'dict'>
print(d['a'])  # apple 
print(d['b'])  # banana

 


 

3) 딕셔너리에 값 추가/제거

 

  ⚡️  딕셔너리에 값을 추가할 때는 키를 기반으로 값을 입력

  ⚡️  setdefault() 메소드를 이용해 추가할 경우 동일한 키가 있는 경우 수정 x

  ⚡️  update() 메소드를 이용해 추가할 경우 동일한 키가 있으면 수정 o

딕셔너리[새로운키] = 새로운 값
dic['watermelon'] = '멜론'
print(dic)  # {'apple': '사과', 'watermelon': '멜론'}

# 존재하는 키값을 이용해서 정의하면, value 수정으로 인식
dic['watermelon'] = '수박'
print(dic)  # {'apple': '사과', 'watermelon': '수박'}

# setdefault() 메소드를 이용한 추가
me = {'name': 'james'}
me.setdefault('age', 20)
print(me)  # {'name': 'james', 'age': 20}
me.setdefault('age', 30) # 동일한 키가 있는 경우에 무시
print(me)  # {'name': 'james', 'age': 20}

# update() 메소드의 경우 존재하는 키값이면 수정
me.update(age=25)
print(me)  # {'name': 'james', 'age': 25}

# update() 메소드의 경우 존재하지 않는 키값이면 추가
me.update(address = 'seoul')
print(me)  # {'name': 'james', 'age': 25, 'address': 'seoul'}

 

 

  ⚡️  del 키워드 or  pop() 메소드를 사용하여 특정 키를 지정하면 해당 요소가 제거

# del 키워드 사용
dic = {'apple' : '사과', 'watermelon' : '수박'}
del dic['apple']  # {'watermelon': '수박'}


# pop() 메소드 사용
dic = {'apple' : '사과', 'watermelon' : '수박'}
dic.pop('watermelon')  # {'apple': '사과'}

 


💡  KeyError 예외

   - 존재하지 않는 키에 접근하면 발생

dic = {}
dic['key']
# -> 존재하지 않는 키이므로 KeyError 발생

 

 


4) 딕셔너리 내부에 키가 있는지 확인

  ⚡️ in 키워드나 get() 함수를 사용해 딕셔너리 내부에 키가 있는지 확인할 수 있다.

# in 키워드 사용
dic = {'a': 'apple', 'b': 'banana', 'c': 'carrot'}
if 'a' in dic:
    print(dic['a'])
else:
    print("존재하지 않는 키에 접근하고 있습니다.)
    
# 실행결과: apple

 

# get() 함수 사용
dic = {'a': 'apple', 'b': 'banana', 'c': 'carrot'}
value = dic.get('b')
print('값 = ', value)  # 값 =  banana

# 존재하지 않는 키 접근
value = dic.get('d')
print('값 = ', value)  
if value == None:
    print('존재하지 않는 키에 접근했습니다.')  
# 실행결과) 
# 값 =  None
# 존재하지 않는 키에 접근했습니다.

 

 

 

 

[ 내용 참고 : IT학원 강의 및 책 '혼자 공부하는 파이썬' ]

+ Recent posts