이 max() 함수를 이용하여 list 를 받아 최대값을 return 해주는 함수를 작성해 보았다.
def max_list(list):
return max(list)
위의 함수를 for loop을 이용하여 다음과 같이 구현해 보았다.
def max_forloop(list):
max = 0
for i in range(len(list)):
if list[i] > max:
max = list[i]
return max
.
두 함수의 성능을 비교해 보자.
같은 리스트를 사용하여 비교하기 위해
매 테스트마다 새로운 리스트를 작성하여
두 함수의 속도를 측정해 보자.
코드는 아래와 같이 작성하였다.
random 함수를 이용하여 10,000,000 개의 정수로 이루어진 list를 만들어서 각각 전달해 주었다.
총 10번씩 반복하며 각각의 실행 시간과 평균 실행 시간을 출력해 주었다.
import time
import random
def make_list(count):
arr = []
for i in range(count):
arr.append(int(random.random()*10000%1000))
return arr
def max_forloop(list):
max = 0
for i in range(len(list)):
if list[i] > max:
max = list[i]
return max
def max_list(list):
return max(list)
time_list_forloop = []
time_list_list = []
for i in range(10):
test_list = make_list(10000000)
time_begin = time.perf_counter()
max_forloop(test_list)
time_end = time.perf_counter()
time_list_forloop.append(time_end - time_begin)
print(f"{i+1}번째 for 실행시간 : {time_end-time_begin}")
time_begin = time.perf_counter()
max_list(test_list)
time_end = time.perf_counter()
time_list_list.append(time_end - time_begin)
print(f"{i+1}번째 max 실행시간 : {time_end-time_begin}")
print(f">>> for 평균 실행시간 : {sum(time_list_forloop)/len(time_list_forloop)}")
print(f">>> max() 평균 실행시간 : {sum(time_list_list)/len(time_list_list)}")
각 테스트 케이스는 한 줄로 이루어져 있으며, 각 줄에 A와 B가 주어진다. (0 < A, B < 10)
출력
각 테스트 케이스마다 A+B를 출력한다.
기존 풀이는 다음과 같다
T = int(input())
test_case = []
for i in range(T):
test_case.append(list(map(int,input().split())))
for x in range(T):
print(test_case[x][0]+test_case[x][1])
위의 문제를 다음과 같이 함수화 하였다.
함수 내에서 한 줄씩 프린트하고 끝낼 수도 있지만,
함수화하는 의미를 부여하기 위해 결과값들을 list 형태로 return해 주는 방식으로 코드를 작성해 보았다.
# 백준 10950번 A+B - 3
def AplusB3():
test_case = []
result_list = []
count = int(input())
for i in range(count):
test_case.append(list(map(int,input().split())))
for x in range(count):
result_list.append(test_case[x][0]+test_case[x][1])
return result_list
print(AplusB3())
n = int(input())
total = 0
for i in range(1,n+1):
total += i
print(total)
위의 문제를 다음과 같이 함수화 하였다.
재귀 함수를 사용하여 작성해 보았다.
# 백준 8393번 합
def addtil1(num):
if num == 1:
return 1
else:
return num + addtil1(num-1)
n = int(input())
print(addtil1(n))
재귀 함수를 사용하다 보니 재귀와 for loop의 성능 차이에 대해 궁금해져서 확인해 보기 위해 코드를 작성해 보았다.
import time
def addtil1_resursion(num):
if num == 1:
return 1
else:
return num + addtil1_resursion(num-1)
def addtil1_for(num):
total = 0
for i in range(num+1):
total += i
return total
n = int(input())
start = time.time()
print(addtil1_resursion(n))
end = time.time()
print(f"resursion : {end-start}")
start = time.time()
print(addtil1_for(n))
end = time.time()
print(f"for-loop : {end-start}")
결과를 확인하기 위해 10,000이상의 큰 수를 넣어보니 Recursion Error 가 발생하였다.
RecursionError: maximum recursion depth exceeded in comparison
python에서는 recursion limit을 기본적으로 1,000으로 둔다는 것을 배웠다.
결과를 확인하기 위해 900 으로 비교해 보았다.
결과값은 동일하였으며 속도 측면에서는 역시 재귀함수보다 for loop 이 빠름을 알 수 있었다.
준원이는 저번 주에 살면서 처음으로 코스트코를 가 봤다. 정말 멋졌다. 그런데, 몇 개 담지도 않았는데 수상하게 높은 금액이 나오는 것이다! 준원이는 영수증을 보면서 정확하게 계산된 것이 맞는지 확인해보려 한다.
영수증에 적힌,
구매한 각 물건의 가격과 개수
구매한 물건들의 총 금액
을 보고, 구매한 물건의 가격과 개수로 계산한 총 금액이 영수증에 적힌 총 금액과 일치하는지 검사해보자.
입력
첫째 줄에는 영수증에 적힌 총 금액X가 주어진다.
둘째 줄에는 영수증에 적힌 구매한 물건의 종류의 수N이 주어진다.
이후N개의 줄에는 각 물건의 가격a와 개수b가 공백을 사이에 두고 주어진다.
출력
구매한 물건의 가격과 개수로 계산한 총 금액이 영수증에 적힌 총 금액과 일치하면Yes를 출력한다.
일치하지 않는다면No를 출력한다.
기존 풀이는 다음과 같다.
X = int(input()) # total price
N = int(input()) # total number of types of objects
product_list = []
total_price = 0
for i in range(N): # total number 만큼 단가와 수량 입력받기
product_list.append(list(map(int,input().split())))
for j in range(N): # 물건값 총 합계 계산
total_price += product_list[j][0] * product_list[j][1]
if X == total_price: # 합계 비교
print('Yes')
else:
print('No')
위의 풀이를 다음과 같이 함수화 하였다.
# 백준 25304번 영수증
def checking_receipt(total_price, total_type):
product_list = []
add_price = 0
for i in range(total_type):
product_list.append(list(map(int,input().split())))
for j in range(total_type):
add_price += product_list[j][0] * product_list[j][1]
if total_price == add_price:
return True
else:
return False
X = int(input())
N = int(input())
print(checking_receipt(X, N))
오늘은 혜아의 면접 날이다. 면접 준비를 열심히 해서 앞선 질문들을 잘 대답한 혜아는 이제 마지막으로 칠판에 직접 코딩하는 문제를 받았다. 혜아가 받은 문제는 두 수를 더하는 문제였다. C++ 책을 열심히 읽었던 혜아는 간단히 두 수를 더하는 코드를 칠판에 적었다. 코드를 본 면접관은 다음 질문을 했다. “만약, 입출력이N바이트 크기의 정수라면 프로그램을 어떻게 구현해야 할까요?”
혜아는 책에 있는 정수 자료형과 관련된 내용을 기억해 냈다. 책에는long int는4바이트 정수까지 저장할 수 있는 정수 자료형이고long long int는8바이트 정수까지 저장할 수 있는 정수 자료형이라고 적혀 있었다. 혜아는 이런 생각이 들었다. “int앞에long을 하나씩 더 붙일 때마다4바이트씩 저장할 수 있는 공간이 늘어나는 걸까? 분명long long long int는12바이트,long long long long int는16바이트까지 저장할 수 있는 정수 자료형일 거야!” 그렇게 혜아는 당황하는 면접관의 얼굴을 뒤로한 채 칠판에 정수 자료형을 써 내려가기 시작했다.
혜아가𝑁바이트 정수까지 저장할 수 있다고 생각해서 칠판에 쓴 정수 자료형의 이름은 무엇일까?
입력
첫 번째 줄에는 문제의 정수𝑁이 주어진다.(4≤𝑁≤1000; 𝑁은4의 배수)
출력
혜아가𝑁바이트 정수까지 저장할 수 있다고 생각하는 정수 자료형의 이름을 출력하여라.
기존 풀이는 다음과 같습니다
N = int(input())
result_string = []
number_long = N // 4
for i in range(number_long):
result_string.append("long")
result_string.append('int')
print(f'{" ".join(result_string)}')
위의 풀이를 다음과 같이 함수화 하였습니다
# 백준 25314번 코딩은 체육과목 입니다
def decide_datatype(byte):
result_string = []
number_long = N // 4
for i in range(number_long):
result_string.append("long")
result_string.append('int')
return " ".join(result_string)
N = int(input())
print(decide_datatype(N))
import sys
T = int(input())
test_case = []
for i in range(T):
test_case.append(list(map(int,sys.stdin.readline().split())))
for x in range(T):
print(test_case[x][0]+test_case[x][1])
위의 풀이를 다음과 같이 함수화 하였습니다
# 백준 15552번 빠른 A+B
import sys
def fastAplusB():
test_case = []
result_case = []
count = int(input())
for i in range(count):
test_case.append(list(map(int,sys.stdin.readline().split())))
for j in range(count):
result_case.append(test_case[j][0]+test_case[j][1])
return result_case
print(fastAplusB())
T = int(input())
test_case = []
for i in range(T):
test_case.append(list(map(int,input().split())))
for x in range(T):
print(f"Case #{x+1}: {test_case[x][0]+test_case[x][1]}")
위의 풀이를 다음과 같이 함수화 하였습니다
# 백준 11021번 A+B - 7
def AplusB7():
T = int(input())
test_case = []
for i in range(T):
test_case.append(list(map(int,input().split())))
for x in range(T):
print(f"Case #{x+1}: {test_case[x][0]+test_case[x][1]}")
AplusB7()
T = int(input())
test_case = []
for i in range(T):
test_case.append(list(map(int,input().split())))
for x in range(T):
print(f"Case #{x+1}: {test_case[x][0]} + {test_case[x][1]} = {test_case[x][0]+test_case[x][1]}")
위의 풀이를 다음과 같이 함수화 하였습니다
# 백준 11022번 A+B - 8
def AplusB8():
T = int(input())
test_case = []
for i in range(T):
test_case.append(list(map(int,input().split())))
for x in range(T):
print(f"Case #{x+1}: {test_case[x][0]} + {test_case[x][1]} = {test_case[x][0]+test_case[x][1]}")
AplusB8()
test_case = []
while True:
temp_arr=[]
a, b = map(int,input().split())
if a==0 and b==0:
break
else:
temp_arr.append(a)
temp_arr.append(b)
test_case.append(temp_arr)
for i in range(len(test_case)):
print(test_case[i][0] + test_case[i][1])
위의 풀이를 다음과 같이 함수화 하였습니다
# 백준 10952번 A+B - 5
def AplusB5():
test_case = []
while True:
temp_arr=[]
a, b = map(int,input().split())
if a==0 and b==0:
break
else:
temp_arr.append(a)
temp_arr.append(b)
test_case.append(temp_arr)
for i in range(len(test_case)):
print(test_case[i][0] + test_case[i][1])
AplusB5()
test_case = []
while True:
temp_arr=[]
try:
a, b = map(int,input().split())
temp_arr.append(a)
temp_arr.append(b)
test_case.append(temp_arr)
except:
break
for i in range(len(test_case)):
print(test_case[i][0] + test_case[i][1])
위의 풀이를 다음과 같이 함수화 하였습니다
# 백준 10951번 A+B - 4
def AplusB4():
test_case = []
while True:
temp_arr=[]
try:
a, b = map(int,input().split())
temp_arr.append(a)
temp_arr.append(b)
test_case.append(temp_arr)
except:
break
for i in range(len(test_case)):
print(test_case[i][0] + test_case[i][1])
AplusB4()
x = int(input())
y = int(input())
if x > 0 :
if y > 0 :
print(1)
else:
print(4)
else:
if y > 0:
print(2)
else:
print(3)
위의 문제를 다음과 같이 함수화 하였다.
# 백준 14681번 사분면 고르기
def return_quadrant(x, y):
if x > 0 :
if y > 0 :
return 1
else:
return 4
else:
if y > 0:
return 2
else:
return 3
x = int(input())
y = int(input())
print(return_quadrant(x,y))
a, b, c = map(int,input().split())
if a == b == c :
print(10000+(a*1000))
elif a==b or b==c or a==c:
if a==b:
print(1000+(a*100))
elif b==c:
print(1000+(b*100))
else:
print(1000+(c*100))
else:
print(max(a,b,c)*100)
위 풀이를 다음과 같이 함수화 하였다
# 백준 2480번 주사위
def prize_dice(a ,b ,c):
if a == b == c :
return 10000+(a*1000)
elif a==b or b==c or a==c:
if a==b:
return 1000+(a*100)
elif b==c:
return 1000+(b*100)
else:
return 1000+(c*100)
else:
return max(a,b,c)*100
a, b, c = map(int,input().split())
print(prize_dice(a,b,c))
이번 문제는 python 내장 함수인 min(), max()를 사용하여 풀면 간단하나, 내장함수를 사용하고 for loop 을 사용하여 푸는 방법에 대해서도 같이 고민해 보았다.
두 방법을 제출하여 사용 메모리와 처리시간에 차이가 있는지도 확인해 보고 싶었다.
>>> 내장 함수를 사용하여 풀이한 방법:
N = int(input())
arr = list(map(int, input().split()))
print(min(arr),max(arr))
>>> for loop을 이용하여 전체를 다 비교하는 방법
N = int(input())
arr = list(map(int, input().split()))
min = arr[0]
max = arr[0]
for i in range(1, N):
if arr[i] > max:
max = arr[i]
elif arr[i] < min:
min = arr[i]
print(min, max)
>>> 백준 사이트 내 결과
제일 아래쪽(시간: 364ms)이 내장함수를 사용하여 제출한 풀이이며, 제일 위는 for loop을 이용하여 제출한 풀이의 결과이다.
리뷰
우선 내장 함수를 이용하는 것이 코드도 간단하고 더욱 빠르게 해결되는 점을 확인할 수 있다.
아무래도 for loop를 이요하여 전체를 다 비교하는 방식보다는 내장함수에서 그보다 빠르게 수행 가능한 binary search같은 방식을 채택하고 있는 듯하다.
그럼 python에서 같이 제공하는 method에는 어떤 차이가 있는지 궁금하여 테스트 해보기로 하였다.
sort()를 이용하여 정렬한 후, list의 최초의 값과 마지막 값을 출력하는 것은 어떤지 확인해 보자.
코드는 다음과 같다.
N = int(input())
arr = list(map(int, input().split()))
arr.sort()
print(arr[0],arr[N-1])
결과는 다음과 같다.
>>> 예상은 했지만 역시 sorting 하는데 시간이 꽤 많이 걸리는 점을 확인할 수 있었다.
결론
python의 장점을 살리기 위해선 지금 내가 필요한 작업에 적합한 내장함수를 최대한 활용하여 코드길이도 줄이고 가독성도 높이면 성능도 좋아질 가능성이 높다.
test_case = []
while True:
temp_arr=[]
try:
a, b = map(int,input().split())
temp_arr.append(a)
temp_arr.append(b)
test_case.append(temp_arr)
except:
break
for i in range(len(test_case)):
print(test_case[i][0] + test_case[i][1])
test_case = []
while True:
temp_arr=[]
a, b = map(int,input().split())
if a==0 and b==0:
break
else:
temp_arr.append(a)
temp_arr.append(b)
test_case.append(temp_arr)
for i in range(len(test_case)):
print(test_case[i][0] + test_case[i][1])