본문 바로가기

Language/python

혼공단 5주차.. 하기 전에 복습먼저 ✅

피보나치수열

counter = 0

def fibonacci(n):
    print("fibonacci({}) 계산 중... ".format(n))
    global counter
    counter += 1
    
    if n == 1:
        return 1
    if n ==2:
        return 2
    else:
        return fibonacci(n-1)+ fibonacci(n-2)
    
    
num = int(input("fibonacci(n) 실습. n을 입력하시오 >> "))
print("factorial({}): {}".format(num,fibonacci(num)))
print("계산에 활용된 덧셈 횟수: ",counter)

결과

50을 입력했더니 끝도 없이 계산중이다...

 

 

메모화

위 코드의 재귀함수는 한번 구했던 값도 다시 구해야 함.

시간이 오래 걸릴 수밖에 없다.

그렇기 때문에 재귀함수는 메모화라는 개념을 사용하여 코드를 작성해야 함. 

dictionary={
    1: 1,
    2: 1
}

def fibonacci(n):
    if n in dictionary:
       #메모가 되어 있으면 메모된 값 확인
        return dictionary[n]
    else:
        #메모되어있지 않다면 값을 구함
        output=fibonacci(n-1) + fibonacci(n-2)
        dictionary[n]=output
        return output
    
print("피보나치(10): ", fibonacci(10))
print("피보나치(10): ", fibonacci(20))
print("피보나치(10): ", fibonacci(30))
print("피보나치(10): ", fibonacci(40))
print("피보나치(10): ", fibonacci(50))

딕셔너리를 사용해서 한번 계산한 값을 저장하여 다음 계산 시 활용할 수 있게 한다.

해당 작업을 "메모"한다고 표현한다.

fibonacci(n) 을 출력한 이후 dictionary 구조가 궁금하다면 다음 코드를 입력하여 확인해보자.

for item in dictionary :
    print("Key:%s\tValue:%d"%(item,dictionary[item]))

 

 

튜플과 람다

튜플: 함수와 함께 많이 사용되는 리스트와 비슷한 자료형이다. 리스트와 다른 점은 한번 결정된 요소는 바꿀 수 없음

람다: 매개변수로 함수를 전달하기 위해 함수 구문을 작성하는 것이 귀찮고, 코드 공간의 낭비라고 생각될 때 함수를 간단하게 선언하는 방법

# 튜플 생성
tuple_test1 = (10,20,30)

# 요소를 하나만 가지는 튜플
tuple_test2 = (10,)
#tuple_test2 = (10)이라고 선언 시 그냥 10이라는 숫자를 괄호로 감싼 것으로 인식.

요소의 변경 불가능한 튜플

 

lambda 매개변수 : 리턴값

 

filter() 함수와 map() 함수

함수를 매개변수로 전달하는 대표적인 두 함수이다.

- map(): 리스트의 요소를 함수에 넣고 리턴된 값으로 새로운 리스트를 구성

- filter(): 리스트의 요소를  함수에 넣고 리턴된 값이 true인 것으로 새로운 리스트를 구성

def power(item):
    return item*item
def under_3(item):
    return item<3

list_input_a=[1,2,3,4,5]

# map() 함수 실행
print("# map() 함수 실행")
output_a=map(power,list_input_a)
print(output_a)
print(list(output_a))
print()

# filter() 함수 실행
print("# filter() 함수 실행")
output_b=filter(under_3,list_input_a)
print(output_b)
print(list(output_b))

 

위 코드를 람다를 사용해서 재작성 해보자.

power = lambda x: x*x
under_3 = lambda x: x<3

list_input_a=[1,2,3,4,5]

# map() 함수 실행
print("# map() 함수 실행")
output_a=map(power,list_input_a)
print(output_a)
print(list(output_a))
print()

# filter() 함수 실행
print("# filter() 함수 실행")
output_b=filter(under_3,list_input_a)
print(output_b)
print(list(output_b))

정상작동

람다는 간단한 함수를 간단하게 선언하는 방법.

위와 같이 따로 선언할 필요 없고.. 그냥 사용할 곳(매개변수)에 곧바로 넣을 수 있다.

list_input_a=[1,2,3,4,5]

# map() 함수 실행
print("# map() 함수 실행")
output_a=map(lambda x: x*x,list_input_a)
print(output_a)
print(list(output_a))
print()

# filter() 함수 실행
print("# filter() 함수 실행")
output_b=filter(lambda x: x<3,list_input_a)
print(output_b)
print(list(output_b))

 

 

파일과 관련된 처리하기

파일 : ⓐ 텍스트 파일 ⓑ 바이너리 파일

두 가지로 나뉘나, 여기서는 텍스트 파일의 경우에만 살펴볼 것.

 

파일 열기

파일 객체 = open(문자열: 파일경로, 문자열: 읽기모드)

읽기모드

- w: write 모드 (새로쓰기모드)

- a: append 모드 (뒤에 이어서 쓰기 모드)

- r: read 모드 (읽기 모드)

 

파일을 닫을 때는 파일 객체.close()

 

 

with 키워드

프로그램이 길어질수록 open() 함수와 close() 함수 사이에 많은 코드가 들어간다.

파일을 열고 닫지 않는 실수를 방지하기 위해 with 키워드 기능이 존재.

with open(문자열: 파일경로, 문자열: 모드) as 파일 객체:
	문장
with open("basic.txt","w") as file:
    file.write("Hello Python Programming...")
#with 구문 종료 시 자동으로 파일 close

 

텍스트 파일 읽기

파일 객체.read()
with open("basic.txt","r") as file:
    contents = file.read()
print(contents)

 

 

[실습] 랜덤하게 1000명의 키와 몸무게 만들기

# 랜덤하게 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))

결과

 

[실습] info.txt의 데이터를 한 줄씩 읽어서 BMI를 계산하는 코드 작성

import re


with open("info.txt","r") as file:
    for line in file:
        (name,weight,height) = line.strip().split(", ") #strip(): 문자열 공백 제거
        
        #데이터가 문제 없는지 확인. 문제가 해당 라인 데이터가 문제가 있으면 지나간다. (continue)
        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()

결과(너무 길어서 생략)