1. 프로그래머스 기초 트레이닝 - 길이에 따른 연산
문제점
문제 설명
정수가 담긴 리스트 num_list가 주어질 때,
리스트의 길이가 11 이상이면 리스트에 있는 모든 원소의 합을 10 이하이면
모든 원소의 곱을 return하도록 solution 함수를 완성해주세요.
제한사항
2 ≤ num_list의 길이 ≤ 20
1 ≤ num_list의 원소 ≤ 9
# num_list = 정수가 담긴 리스트
# return은 num_list의 길이가 11 이상이면 원소의 합을, 아니면 원소의 곱을 리턴
시도해 본 것들
sum, if문, for문 사용
def solution(num_list):
answer = 1
for num in num_list:
answer *= num
return sum(num_list) if len(num_list) > 10 else answer
문자열의 길이가 11이 넘는 경우 sum()을 통한 합 return, 아닐 경우 for문을 통한 곱 return
10 이하인 경우의 코드 줄여보기
return sum(num_list) if len(num_list) > 10 else answer *num_list
return sum(num_list) if len(num_list) > 10 else 1* [*num_list]
모두 리스트를 그대로 출력함
print('*'.join(str(*[num_list]))) #[*2*,* *3*,* *4*,* *5*]
join에서 언패킹을 하는데 *[num_list]로 또 풀면서 전혀 예상 못한 출력 발생
print('*'.join([str(num) for num in num_list])) #2*3*4*5
print(int('*'.join([str(num) for num in num_list]))) #ValueError
문자열을 내가볼 때는 계산이 가능한 형태로 만들었지만, int로 형변환을 했을 때 실제로 계산이 실행되지 않음
구글링을 통한 eval() 사용
def solution(num_list):
return sum(num_list) if len(num_list) > 10 else eval('*'.join([str(num) for num in num_list]))
eval()로 감싸게 되면 컴퓨터가 해석 가능한 수식이 문자열로 존재할 때 그 수식을 실행해 준다.
해결 방법
def solution(num_list):
return sum(num_list) if len(num_list) > 10 else eval('*'.join([str(num) for num in num_list]))
코드의 길이는 줄었지만, eval() 함수가 문자열을 수식으로 변환하면서 다양한 경우를 포함하고 그 다양한 경우에 내가 상정하지 않은 상황까지 포함되어 보안상 이슈가 생긴다.
GPT의 선택
def solution(num_list):
answer = 1
for num in num_list:
answer *= num
return sum(num_list) if len(num_list) > 10 else answer
알게 된 점
eval() 함수를 알게 됐다.
eval()은 문자열로 수식을 실행하기 때문에 내가 의도치 않은 상황에서 코드가 실행되면서 보안에 이슈가 생길 수 있음을 알게 됐다.
1. 팀원과의 코드리뷰 - 직사각형 별 찍기
문제점
문제 설명
이 문제에는 표준 입력으로 두 개의 정수 n과 m이 주어집니다.
별(*) 문자를 이용해 가로의 길이가 n, 세로의 길이가 m인 직사각형 형태를 출력해보세요.
제한 조건
n과 m은 각각 1000 이하인 자연수입니다.
시도해 본 것들
for문 사용하기
a, b = map(int, input().strip().split(' '))
for _ in range(b):
print('*'*a)
먼저 생각난 for문을 이용해서 푼 풀이
List Comprehension을 이용한 풀이
a, b = map(int, input().split())
print(* ['*' * a for _ in range(b)],sep='\n')
최근에 알게 된 List Comprehension과 언패킹을 동시에 사용했다.
'*' * a를 for _ in range(b)를 통해서 b만큼 반복한 리스트 생성
리스트를 *(언패킹) 하면서 , sep='\n'을 통해서 리스트의 원소가 바뀔 때마다 띄어쓰기 대신 \n을 통한 개행
좋다고 생각한 팀원의 코드
a, b = map(int, input().strip().split(' '))
print((a*'*'+'\n') * b)
for문이 없으면서 코드의 길이도 짧은 코드다.
'*' * a이 끝나면 \n을 넣어서 개행하고 *b로 여러 개를 생성
해결 방법
# strip() = 문자열의 시작과 끝에서 ()안에 있는 문자 제거, 없으면 공백 제거
# split() == split(' ') 명시적으로 표시 안해도 빈값이면 공백 제거
a, b = map(int, input().split())
print(* ['*' * a for _ in range(b)],sep='\n')
코드를 이렇게 바꿨는데 GPT에서 코드의 추천도를 물어봤는데 좋은 코드는 아니라고 했다.
GPT의 선택
a, b = map(int, input().strip().split(' '))
for _ in range(b):
print('*'*a)
알게 된 점
a, b = map(int, input().strip().split(' '))
print((a*'*'+'\n') * b)
이 코드도 for문을 사용하지는 않았지만, 구조가 for문을 사용한 것과 동일해서 시간복잡도가 다른 코드들과 일치했다.
1. 팀원과의 코드리뷰 - 수박수박수박수박수박수?
문제점
문제 설명
길이가 n이고, "수박수박수박수...."와 같은 패턴을 유지하는 문자열을 리턴하는 함수,
solution을 완성하세요. 예를들어 n이 4이면 "수박수박"을 리턴하고 3이라면 "수박수"를 리턴하면 됩니다.
제한 조건
n은 길이 10,000이하인 자연수입니다.
시도해 본 것들
for문과 조건문 사용하기
def solution(n):
# n은 정수
# return은 n에 따라 수or박
answer = ''
for i in range(n):
if i % 2 == 0:
answer += '수'
else:
answer += '박'
return answer
시작이 0부터 일 때 짝수=수, 홀수=박 이므로 if문을 통한 판별과 for문을 사용해 n만큼 반복
삼항 연산자를 통해 리팩토링
def solution(n):
answer = ''
for i in range(n):
answer += '수' if i % 2 == 0 else '박'
return answer
로직 자체는 같지만 코드가 간결해짐
List Comprehension 사용
def solution(n):
# '수' if i % 2 == 0 else '박'이런 조건을 가진 i를 for i in range(n)에서 리스트로 만들기
return ''.join(['수' if i % 2 == 0 else '박' for i in range(n)])
아직 List comprehension에 먼저 조건을 선언하고 그 후 for문을 사용하는 방식이 익숙하지 않다.
기존에 사용하던 방법은 for문의 안에서 if문을 사용하면서 값을 찾는데 이건 if문으로 조건을 먼저 설정하고 for문을 사용한다.
좋다고 생각한 팀원의 코드
def solution(n):
answer = ''
# water_melon="수박"
if n%2==0:
# answer+=water_melon*(n//2)
answer+="수박"*(n//2)
else:
# answer=water_melon*(n//2)+water_melon[0]
answer+="수박"*(n//2)+"수"
return answer
def solution(n):
# 짝수일 경우
if n%2 == 0:
return '수박'*(n//2)
# 홀수일 경우
else:
return '수'+'박수'*(n//2)
두 코드 모두 반복문 없이 바로 결과가 나오는 코드다.
팀원의 코드 리팩토링
def solution(n):
return "수박"*(n//2) if n%2==0 else "수박"*(n//2)+"수"
삼항 연산자를 사용해 for문 없이 사용 가능한 코드가 완성됐다. 내가 쓴 코드보다 무슨 뜻을 의미하는지 알기 쉬운 것 같다.
해결 방법
GPT의 선택
def solution(n):
return ''.join(['수' if i % 2 == 0 else '박' for i in range(n)])
for문이 List Comprehension 내부에 존재하지만 CPython 인터프리터를 사용해 속도가 빠르다고 한다.
알게 된 점
List Comprehension 내부에서 실행되는 for문은 CPython 인터프리터를 통해서 빠르게 처리된다고 한다. 그러면 단순히 숏코딩이 아니라 시간복잡도의 개선에도 영향이 있기는 하다.
반복문이 아니어도 *를 사용하면 시간복잡도가 비슷해진다는 것을 알았다.
'개발일지 > TIL' 카테고리의 다른 글
TIL 23-04-28 페어 프로그래밍 - 특별한 이차원 배열2 (0) | 2023.04.28 |
---|---|
TIL 23-04-27 팀원과의 코드리뷰 - 특별한 이차원 배열 1 (0) | 2023.04.27 |
TIL 23-04-25 백준 알고리즘 - 수 정렬하기 3 (0) | 2023.04.25 |
TIL 23-04-24 팀원과의 알고리즘 코드리뷰 - 양꼬치 (0) | 2023.04.24 |
TIL 23-04-23 백준 알고리즘 - 달팽이는 올라가고 싶다 (0) | 2023.04.23 |