5장 함수
5-3. 함수 고급
1) 튜플, 람다
* 튜플
- 리스트는 요소 변경이 가능하지만 튜플은 요소 변경이 불가능
- 그리고 튜플은 ()를 사용 (리스트는 [] 사용하지만)
- 사용법은 리스트와 같음
- []은 변경 되지만 ()은 변경 불가능
# 튜플 = 리스트와 거의 유사
tuple_a = (1,2,3)
# 튜플의 원소에 접근하여 출력
print(tuple_a[0]) # 출력 결과: 1
print(tuple_a[1]) # 출력 결과: 2
print(tuple_a[2]) # 출력 결과: 3
tuple_a[0] = 10 # 튜플은 원소의 값 변경이 불가능하므로 에러 발생
# 튜플은 immutable(불변)한 자료형으로, 한 번 생성된 후에는 원소의 값을 변경할 수 없음
# 따라서 tuple_a[0] = 10과 같이 원소의 값을 변경하려고 하면 에러가 발생함
# 소괄호가 없는 튜플
[a,b] = [1,2]
(c,d) = (3,4)
print(a,b,c,d)
e = 1,2,3,4
print(e)
print(type(e))
f,g,h = 5,6,7
print(f,g,h)
a,b = 1,2
print("교환하기 전의 a,b의 값 : {},{}".format(a,b))
a,b = b,a
print("교환하기 전의 a,b의 값 : {},{}".format(a,b))
# 튜플과 함수
def test():
return (1,2)
a,b = test()
print(a,b)
# 튜플을 리턴하는 함수
for i, j in enumerate([1,2,3,4]):
print("인덱스: {}, 값: {}".format(i,j))
# 딕셔너리 # 동일한 결과값
for i, j in {0:1,1:2,2:3,3:4}.items():
print("인덱스: {}, 값: {}".format(i,j))
a,b= 63, 30
print(a//b)
print(a%b)
c,d =divmod(a,b)
print(c,d)
2) 람다
- 함수를 간단하고 쉽게 선언하는 방법 (일회용)
# 람다
def repeatten(fx):
for i in range(10): # 10번 반복하는 for 루프
fx() # 인자로 받은 함수 fx()를 호출
def printhi():
print("Hi")
repeatten(printhi) # printhi 함수를 repeatten 함수에 인자로 전달하여 10번 "Hi"를 출력하도록 동작
3) 튜플과 람다 비교
# map & filter (함수, 리스트)
def power(item):
return item**2
def under_3(item):
return item < 3
list_a = [1, 2, 3, 4, 5]
output_map = map(power, list_a) # map 함수를 사용하여 list_a의 각 요소에 power 함수를 적용하여 새로운 리스트를 생성
print(output_map)
print(list(output_map)) # map 함수를 사용하여 생성된 리스트를 출력
output_filter = filter(under_3, list_a) # filter 함수를 사용하여 list_a의 각 요소에 under_3 함수를 적용하여 조건을 만족하는 요소만으로 이루어진 새로운 리스트를 생성
print(output_filter)
print(list(output_filter)) # filter 함수를 사용하여 생성된 리스트를 출력
# 람다로 변경
power = lambda x: x**2 # 람다 함수를 사용하여 x의 제곱을 반환하는 함수를 정의
under_3 = lambda x: x<3 # 람다 함수를 사용하여 x가 3보다 작은지를 확인하는 함수를 정의
list_a = [1, 2, 3, 4, 5]
output_map = map(power, list_a) # map 함수를 사용하여 list_a의 각 요소에 power 함수를 적용하여 새로운 리스트를 생성
print(output_map)
print(list(output_map)) # map 함수를 사용하여 생성된 리스트를 출력
output_filter = filter(under_3, list_a) # filter 함수를 사용하여 list_a의 각 요소에 under_3 함수를 적용하여 조건을 만족하는 요소만으로 이루어진 새로운 리스트를 생성
print(output_filter)
print(list(output_filter)) # filter 함수를 사용하여 생성된 리스트를 출력
# 더 단축시키기
list_a = [1, 2, 3, 4, 5]
output_map = map(lambda x: x**2, list_a) # map 함수를 사용하여 list_a의 각 요소에 람다 함수를 적용하여 새로운 리스트를 생성
print(output_map)
print(list(output_map)) # map 함수를 사용하여 생성된 리스트를 출력
output_filter = filter(lambda x: x<3, list_a) # filter 함수를 사용하여 list_a의 각 요소에 람다 함수를 적용하여 조건을 만족하는 요소만으로 이루어진 새로운 리스트를 생성
print(output_filter)
print(list(output_filter)) # filter 함수를 사용하여 생성된 리스트를 출력
* 파일 저장 및 with 코드 (자동으로 파일이 닫히는)
# 파일 처리
# 파일 열고 닫기
file = open("basic.txt","w")
# 텍스트 쓰기
file.write("안녕 파이썬 재밌니")
# 파일 닫기
file.close()
# 키워드 with 로 변경
# 파일 열고 닫기
with open("basic.txt","w")as file:
# 파일에 텍스트를 씁니다.
file.write("0418 비내리는 날")
# 텍스트 읽기
with open("basic.txt","r")as file:
con = file.read()
print(con)
* csv 텍스트 파일을 만든 것을 토대로 반복문 실행하기 // bmi 구분하기
# 텍스트 한 줄씩 읽기
# csv 텍스트 파일 만들기
import random
hg = list("가나다라마바사아자차카타파하")
# info.txt 파일을 쓰기 모드로 열기
with open("info.txt", "w") as file:
# 1000번 반복하여 텍스트 파일에 데이터 쓰기
for i in range(1000):
# 이름, 몸무게, 키를 랜덤하게 생성
name = random.choice(hg) + random.choice(hg) + random.choice(hg)
weight = random.randrange(40,150)
height = random.randrange(130,210)
# 텍스트 파일에 데이터 쓰기
file.write("{}, {}, {}\n".format(name, weight, height))
# 데이터를 한 줄씩 읽기 - 변수 새로 만들기
with open("info.txt","r") as file:
for line in file:
(name, weight, height) = line.strip().split(", ") # line = 이름, 몸무게,키
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()
# 파일 만들 때 공백을 안 넣어서 공백 제거가 의미가 없어졌던 부분임
* 키워드 매개변수 활용
# 리스트 함수를 딕셔너리에서 사용
books = [{"제목":"A",
"가격":10000},
{"제목":"B",
"가격":20000},
{"제목":"C",
"가격":30000}]
def price(book):
return book["가격"]
print(min(books,key = price))
print(max(books,key = price))
# 람다로 변경
books = [{"제목":"A",
"가격":10000},
{"제목":"B",
"가격":20000},
{"제목":"C",
"가격":30000}]
print(min(books,key = lambda book: book["가격"]))
print(max(books,key = lambda book: book["가격"]))
* 오름차순, 내림차순
# 리스트 정렬
# 오름차순
a = [1,25,34,7,15]
a.sort()
print(a)
# 리스트 정렬
# 내림차순
a = [1,25,34,7,15]
a.sort(reverse=True)
print(a)
# sort 적용
books = [{"제목":"A",
"가격":10000},
{"제목":"B",
"가격":20000},
{"제목":"C",
"가격":30000}]
books.sort(key = lambda book: book["가격"],reverse= True )
print(books)
4) 확인문제 352p
* 1번 (숫자를 문자열로 출력)
numbers = [1,2,3,4,5,6]
# map 함수를 사용하여 numbers 리스트의 원소들을 문자열로 변환
# map 함수는 원소들을 지정된 함수(str 함수)에 적용하여 새로운 리스트를 반환
# 하지만 map 함수는 iterator 객체를 반환하므로, 바로 출력하면 주소 값이 출력됨
print(map(str,numbers)) # 출력 결과: <map object at [주소값]>
# map 함수를 사용하여 numbers 리스트의 원소들을 문자열로 변환하여 새로운 리스트를 생성
# list 함수를 사용하여 iterator 객체를 리스트로 변환하여 출력
print(list(map(str,numbers))) # 출력 결과: ['1', '2', '3', '4', '5', '6']
# map 함수를 사용하여 numbers 리스트의 원소들을 문자열로 변환하고, "::" 문자열로 연결하여 출력
# join 함수를 사용하여 리스트의 원소들을 지정된 문자열로 연결
print("::".join(map(str,numbers))) # 출력 결과: '1::2::3::4::5::6'
* 2번
# 확인 문제 1번 352p
numbers = list(range(1,10+1))
print("# 홀수만 추출하기")
print(list(filter(lambda x: x%2 != 0,numbers)))
print()
print("# 3이상, 7 미만 추출하기")
print(list(filter(lambda x: 3<=x<7,numbers)))
print()
print("# 제곱하기")
print(list(filter(lambda x: x**2<50,numbers)))
5) 도전문제 354p (하노이의 탑)
* 1번
# 도전 문제 1
def hanoi(n, from_tower, to_tower, aux_tower):
if n == 1:
print(from_tower, "->", to_tower) # 원판이 1개일 경우에는 그냥 직접 옮김
else:
hanoi(n-1, from_tower, aux_tower, to_tower) # 원판 n-1개를 보조 기둥으로 옮김
print(from_tower, "->", to_tower) # 원판 n을 목적 기둥으로 옮김
hanoi(n-1, aux_tower, to_tower, from_tower) # 보조 기둥에 있는 n-1개의 원판을 목적 기둥으로 옮김
n = int(input("원판의 개수를 입력해주세요:")) # 원판 개수 입력 받음
hanoi(n, "A", "B", "C") # A 기둥에서 C 기둥으로 원판을 옮기는 과정 출력
* 2번
# 도전 문제 2
def hanoi(n, from_tower, to_tower, aux_tower):
if n == 1:
print(from_tower, "->", to_tower) # 원판이 1개일 경우에는 그냥 직접 옮김
return 1 # 이동 횟수 1 추가
else:
count = 0 # 이동 횟수를 카운트하는 변수
count += hanoi(n-1, from_tower, aux_tower, to_tower) # 원판 n-1개를 보조 기둥으로 옮기는 과정의 이동 횟수를 추가
print(from_tower, "->", to_tower) # 원판 n을 목적 기둥으로 옮김
count += 1 # 이동 횟수 1 추가
count += hanoi(n-1, aux_tower, to_tower, from_tower) # 보조 기둥에 있는 n-1개의 원판을 목적 기둥으로 옮기는 과정의 이동 횟수를 추가
return count # 전체 이동 횟수 반환
n = int(input("원판의 개수를 입력해주세요:")) # 원판 개수 입력 받음
total_count = hanoi(n, "A", "B", "C") # A 기둥에서 C 기둥으로 원판을 옮기는 과정 출력 및 이동 횟수 반환
print("총 이동 횟수:", total_count) # 총 이동 횟수 출력
* 스택 : 기본 자료형이 저장된 곳. // 기본자료형이란 : 문자열, 숫자, 불
import matplotlib.pyplot as plt
# 원판을 옮기는 함수
def hanoi(n, from_tower, to_tower, aux_tower):
if n == 1:
print(from_tower, "->", to_tower)
plt.plot([from_tower, to_tower], [0, 1], 'ro-') # 이동 경로를 시각화
else:
hanoi(n-1, from_tower, aux_tower, to_tower)
print(from_tower, "->", to_tower)
plt.plot([from_tower, to_tower], [0, 1], 'ro-') # 이동 경로를 시각화
hanoi(n-1, aux_tower, to_tower, from_tower)
# 원판 개수 입력 받음
n = int(input("원판의 개수를 입력해주세요:"))
# 그래프 설정
fig = plt.figure(figsize=(5, 5))
plt.axis('off')
plt.xlim([-1, 3])
plt.ylim([-0.2, 1.2])
# 타이틀
plt.title(f'Hanoi Tower (n={n})')
# 초기 위치 표시
for i in range(n):
plt.text(i, 0, str(i+1), ha='center', va='center')
# 하노이 탑 알고리즘 실행 및 시각화
hanoi(n, 'A', 'C', 'B')
# 그래프 출력
plt.show()
6장 예외 처리
1. 구문 오류와 예외
1) 조건문 예외 처리 // 한정적으로 경우를 걸 경우에만 해당 됨
# 오류 수정
print("리스트 불러보자")
list_z = [1,2,3]
list_z[0]
# 예외 상황 만들기 - 숫자로 변환할 수 없는 값을 입력한 경우
no = input("정수 입력>")
no = int(no)
print("원의 반지름", no)
print("원의 둘레", 2*3.14*no)
print("원의 넓이", 3.14*no*no)
# 조건문으로 예외 처리
no = input("정수 입력>")
if no.isdigit(): # 숫자로 변환할 수 있는 값을 입력한 경우
no = int(no)
print("원의 반지름", no)
print("원의 둘레", 2*3.14*no)
print("원의 넓이", 3.14*no*no)
else: # 나머지 = 숫자로 변환할 수 있는 값을 입력하지 않은 경우
print("숫자가 입력되지 않았습니다. 정수를 입력하세요")
2) try except
# try except 구문으로 예외 처리
try:
no = input("정수 입력>")
no = int(no)
print("원의 반지름", no)
print("원의 둘레", 2*3.14*no)
print("원의 넓이", 3.14*no*no)
except:
print("숫자가 아닙니다. 정수만 입력해주세요")
# try except 구문으로 예외 처리
try:
no = input("정수 입력>")
no = int(no)
print("원의 반지름", no)
print("원의 둘레", 2*3.14*no)
print("원의 넓이", 3.14*no*no)
except:
pass
3) try except else // finally 사용
# try except else 구문으로 예외 처리
try:
no = input("정수 입력>")
no = int(no)
except:
print("정수를 입력해주시겠어요")
else:
print("원의 반지름", no)
print("원의 둘레", 2*3.14*no)
print("원의 넓이", 3.14*no*no)
# try except else finally 구문으로 예외처리
try:
no = input("정수 입력>")
no = int(no)
except:
print("정수를 입력해주시겠어요")
else:
print("원의 반지름", no)
print("원의 둘레", 2*3.14*no)
print("원의 넓이", 3.14*no*no)
finally:
print("프로그램은 어떻게든 종료가 되었어요")
* 핵심
1) 중요한 구문 조합 (finally)
try + except 구문
try + except + finally 구문
try +finally 구문
* 링크 (직접 글 쓴 당사자만 확인 가능 // 계정 이동해서 확인하기)
https://colab.research.google.com/drive/1RoC4AJZc5zyeYfZ-6gCFQ7HlGBBHUSKf?usp=sharing
* 오늘의 링크
파이썬 코드 시각화 링크.
'배운 책들 정리 > 혼자 공부하는 파이썬' 카테고리의 다른 글
혼자 공부하는 파이썬 8 - 객체, 클래스, 메소드 // 복습 (0) | 2023.04.20 |
---|---|
혼자 공부하는 파이썬 6,7 - 예외 처리, 모듈 (1) | 2023.04.19 |
혼자 공부하는 파이썬 5 - 함수 만들기, 함수의 활용 (1) | 2023.04.17 |
혼자 공부하는 파이썬 4 - 문자열, 리스트, 딕셔너리와 관련된 기본 함수(while,range,reversed,enumerate,Counter 등등) (0) | 2023.04.14 |
혼자 공부하는 파이썬 4 - 반복문(조건문 응용(if), dict, list, 이중for문, range, while문) (0) | 2023.04.13 |