아니 이제 앞으로 좀 매일 배운것을 적는 시간을 가져야할 것 같다.
생각도 정리할겸사겸사 그래서 하루를 파트를 최소한 3개로 나눠서 매 시간을 한 것을 좀 분배하고 써 놓으면 좋을것 같다 아 좀 배고픈듯...
heapq 모듈에서는 최소힙밖에 만들 수 없기 때문에 다음과 같은 방법이 있다.
1. 튜플로 (-value, value)로 heap으로 넣어주는 법
from heapq import heappush, heappop
nums =[4,1,7,3,8,5]
heap =[]
for num in nums:
heappush(heap, (-num, num))
while heap:
print(heappop(heap))
import heapq
heap = []
values = [1,5,3,2,4]
# 아래 for문을 실행시키고 나면 heap은 [-5,-4,-3,-1,-2]가 된다.
for value in values:
heapq.heappush(heap, -value)
# 아래 for문을 실행시키면 5,4,3,2,1이 출력된다. 즉, 큰 숫자부터 출력이 된다.
for i in range(5):
print(-heapq.heappop(heap))
9시 20분 문제 발생!
TypeError: pop() takes 0 positional arguments but 1 was given
라고 뜬다...
와... 이거는 좀 중요!
function을 class안에서 만들 때 self를 꼭 넣어주도록 하자!
self를 넣어줘야만 자신의 정보를 끌어낼 수 ? 있는 것 같다
먼저 class 만들 때 함수를 설정할때
def __init__(self):
self.items = []
self.info = info
와 같이 설정을 꼭 해주는데 객체생성에 필수적이니까 까먹지 않도록 하자
TypeError: 'tuple' object doesn't support item deletion
이렇게 타입에러가 난다고 볼 수 있고 처리하려면 요즘 즐겨 쓰는 try, except TypeError로 처리해주면 좋을 것 같다.
일단 이 문제를 야무지게 풀기전에 heapq에 모듈들이 생각보다 많던데 읽어보도록 하자.
이제 알겠는데 가운데를 말해요에서 nlargest가 쓰일 수도 있을 것 같다는 생각을 해본다.
from heapq import heappush, nsmallest
import sys
heap = []
n_command = int(sys.stdin.readline())
for _ in range(n_command):
heappush(heap, int(sys.stdin.readline()))
# 짝수 일 때
if len(heap) % 2 == 0:
print(nsmallest(len(heap)//2, heap)[-1])
else:
print(nsmallest((len(heap)+1)//2, heap)[-1])
아 젬장 답지 참고하기 싫은데
2. 두개의 힙을 이용 leftheap, rightheap이라고 가정
leftheap은 최대힙으로 가정
rightheap은 최소힙으로 가정
가장 중요한 heap의 성질을 사용한다는 것! root를 꺼내는 것의 장점
1) 하나 들어왔을 때
-> leftheap에 넣기
-> leftheap에서 꺼내기
2) 두번째 들어왔을 때
-> rightheap에 넣기
-> root 비교해주기! 비교한다면 왼쪽이 더 크면 바꿔서 넣어주기
여기서 왠지 heappushpop을 쓸 수 있을 까 싶긴한데~~ 더 깔끔하게 써볼수 있을 것 같당
-> leftheap에서 꺼내기
한두번 해보면 야무지게 확인가능하다! 좋아좋아
역시 어제 한 10시에 자고 오늘 일곱시쯤 일어나니까 뭔가 머리가 팽글팽글 도는구먼
한 몇시간 잔거지 10시부터 잣으니까 거의 9시간 잔것! 확실히 잠을 잘 자고 카페인 아침 점심으로 사발로 때려주면 컨디션이 꽤 낟밷낟밷
또 아침에 라떼 우유반 샷추가 했더니 약간 이게 내 컨디션 회복의 근원인듯
근데 이렇게 아침에 정리하는 것 생각보다 좋은 것 같다
Any funckin ways
다음과 같이 heap을 왼쪽 오른쪽으로 나누어서 풀게 되면 다음과 같다
from heapq import heappush, heappop
import sys
left_heap = [] # 최대 힙
right_heap = [] # 최소 힙
n_command = int(sys.stdin.readline())
for _ in range(n_command):
going_in = int(sys.stdin.readline())
if len(left_heap) == len(right_heap):
heappush(left_heap, (-going_in, going_in))
else:
heappush(right_heap, (going_in, going_in))
# check_stage
try:
if left_heap[0][1] > right_heap[0][0]:
left_out = heappop(left_heap)[1]
right_out = heappop(right_heap)[0]
heappush(right_heap, (left_out, left_out))
heappush(left_heap, (-right_out, right_out))
except IndexError:
pass
print(left_heap[0][1])
왠지 알고리즘만 푸는 것 물론 좋긴한데... 파이썬을 야무지게 쓰고 싶은 욕심이 크기 때문에 왠만하면 좀 정리도 같이 하려고한다.
일단 클라쓰를 작성할때에는
class Sample:
'''
Sample Class
Author: Hojun
Date: 2023. 03. 14
'''
car_count = 0
def __init__(self, item):
self._item = item
def some_function(self):
여기서
init : double leading underscore 스페셜 변수나 매직 메서드에 사용되는 컨벤션, 특정문법적 기능을 제공하거나 특정한 일 수행.
_happy : single leading underscore, 프라이빗 변수,클라스, 메서드를 선언할 때 사용되는 컨벤션으로 from module import *하게 되면 모두 임포트에서 모두 무시하게된다.
happy_ : single trailing underscore, 키워드 충돌을 피할려고 쓰는데 별로 안쓸것.
와 같이 특별한 네이밍을 할 경우가 있다고 한다.
클라쓰에서 다음과 같이 넣어주면서 내용을 적어주는게 고수의 길이라고 한다
"""
내용을 넣기
"""
또한 def method(self): 와 같이 항상 이렇게 self를 넣어야만 자기 인스턴스에 있는 value를 가지고 올 수 있다는 것아다.
방금 확인한건데
str 이랑 repr 은 프린트를 해보면 알 수 있다
1) print(객체) -> str 에 적어놓은 값이 나오고
2) 객체 -> repr 이 나온다고 할 수 있다
#1. 상위로부터 상속받은 모든 메소드를 넣어 리스트를 만들어서 준다
print(dir(car1))
#2. 내가 지정한 메소드들을 받아올 수 있다
print(sameple_class_object.__dict__)
#3. 앞에 적어둔 내용 """내용"""을 출력해서 적어줄 수도 있다.
print(Class 혹은 오브젝트.__doc__)
해준다면 확실히 이 클라스의 정보를 압축해서 읽을 수 있다.
self 인자를 꼭 넘겨줘야만하는데 예를 들어 class Car: 이렇게 define 해서 하나를 만들었을 때
Car.detail_info() 만 햇을때는 self 인자를 불러오지 않았기 때문에
TypeError: detail_info() missing 1 required positional argument: 'self'
가 뜨게 된다!
해결 방법은 다음과 같다
1. car2.detail_info()를 하게 되면 자연스레 self를 불러오게 되니까 성립
2. Car.detail_info(car2)를 하게되면 성립
1번이 성립되는 이유는 init 을 해줄 때 가지고 올 수 있어서인가?
class에서 변수를 생성해놓을 때 세팅을 해논다고 생각해야 될 것 같다. self가 없다면 세팅이 없는 것을 자겨온다는 의미?
class 변수는
Sample.car_count 를 뽑아보게 된다면 모든 클라스가 함께 공유하는 변수를 의미하게 된다.