내일배움캠프 15일차
[오늘 한일]
- 알고리즘 문제풀이
- 장고 강의 수강
- ERD 특강 수강
[오늘 배운점]
내 부족한 점을 하나 알게 되었다.
배우는 거나 코드를 쓰는 건 빠른 편이라고 생각하는데,
다른 사람이 작성한 코드의 의도를 해석하는 데는 시간이 꽤 걸린다.
어제도 '연속된 정수의 합' 문제에, 다른 팀원분의 풀이를 이해하는데 한참 걸렸는가 하면,
오늘은 '문자열 정렬하기'에서 반복문 조건문의 동작을 계속 엉뚱하게 생각하기도 했다.
본래 나는 생각하는 속도가 느린 사람이긴 하다.
내가 내 의도로 코드를 작성했을때는 한눈에 잘 보고 기억하지만,
다른 사람이 만든 코드를 보며 하나씩 해석할때는 그 느린 속도가 나온다.
이런 부분도 연습한다면 성장할 수 있지 않을까 생각해본다.
<문자열을 반복하면 한글자씩 본다>
for i in 문자열
반복문에 문자열을 넣으면,
맨 앞글자부터 끝 글자까지 한글자씩 반복한다.
어제 '가위바위보' 문제를 풀때 그냥 자연스럽게 터득했다.
(문자열을 반복문에 넣으면 한글자씩 돌지 않을까 했는데 그게 맞았다.
어딘가 강의에서 한번 들었었어서 떠오른 건지도 모르겠다.)
그런데 우연찮게도 오늘 도전한 3개 문제중 2문제가 또 문자열 문제였다.
(비슷한 문제끼리 묶어 놓으신 이유일 것이다.)
그래서 문제들을 풀어보며 알게된 포인트 들을 적어본다.
1. 위 코드처럼 문자열을 반복했을때 얻게 되는 각 글자 i는 역시 문자열(string)이다.
그렇다면 '문자열 정렬하기' 문제의 요구처럼,
문자열 중 정수인 문자열만 골라내야 한다면 어떻게 할수 있을까.
나는 먼저 isdigit함수가 생각났다.
isdigit함수가 정확히 그 동작을 해줄 수 있다.
(저번 팀과제에서 써봤기 때문에 알고있었다.)
다만 내장 함수를 쓰지않고 풀어보려고 했는데 어떤 부분에서 막혔다.
그래서 우선 isdigit으로 해답을 작성해봤다.
str_1 = "hi12392"
str_2 = "p2o4i8gj2"
str_3 = "abcde0"
def solution(my_string):
answer = []
for i in my_string:
if i.isdigit():
answer.append(int(i))
answer.sort()
return answer
print(solution(str_1)) #[1, 2, 2, 3, 9]
print(solution(str_2)) #[2, 2, 4, 8]
print(solution(str_3)) #[0]
작성한 코드는 위와 같다.
isdigit함수를 이용해서 단순하게 정수를 검사하고 리스트에 대입할 수 있었다.
2. 문자열을 리스트에 담으면 작은 따옴표가 붙는다. 타입이 string이라는 걸 말해준다.
answer.append(i) #['1', '2', '2', '3', '9']
answer.append(int(i)) #[1, 2, 2, 3, 9]
위 코드에서 append 부분만 따로 가져왔다.
처음에는 윗줄처럼 작성했는데 결과가 저렇게 나왔다.
즉, i가 문자열이라 작은 따옴표가 붙은 것이다.
예시처럼 출력하기 위해, 아래처럼 int()로 타입을 바꾸어 리스트에 담았다.
그럼 어차피 정수타입으로 바꿀거면 i를 정수타입으로 바꾸는 가공에서의,
동작 차이를 통해 정수를 검출할수도 있지 않을까?
(사실 팀원분 한분이 주신 아이디어 였고,
동시에 isdigit을 안쓰는 풀이 시도에서 막혔던 부분이기도 하다.)
정수인 문자열을 int()하면 정수타입으로 바뀌지만,
문자인 문자열을 int()하면 에러가 난다.
def solution(my_string):
for i in my_string:
if int(i): #ValueError: invalid literal for int() with base 10
그래서 처음 생각해봤던 이러한 방법으로는 에러가 난다.
그런데 위에 적은 대로 그 동작 차이를 이용한다면?
def solution(my_string):
answer = []
for i in my_string:
try:
check = int(i)
answer.append(check)
except:
pass
answer.sort()
return answer
이렇게 두번째 해법을 작성해봤다.
try, except문을 이용해서 int(i)가공을 할때 에러가 나면 넘어가고 에러가 나지 않으면,
즉 정수이면 check을 통해 리스트에 담는 것이다.
어쨌든, 첫 생각에 대해서도 해결을 봤다.
3. 문자열을 다시 조립하는건 쉽다. 그런데 다시 특정 문자를 지우는건 어렵다.
answer = ''
for i in my_string:
if i not in answer:
answer += i
만약 입력 문자열을 가공해서, 다시 문자열을 출력해야 한다면,
반복되는 각 글자 i를 다시 문자열로 조립해야 할 것이다.
이때는 문자열+문자열로 쉽게 문자열을 이어 붙여 줄수 있다.
그럼 이어 붙인 특정 문자를 다시 지우는(떼내는) 방법이 있을까?
'중복된 문자제거' 문제를 풀다가 부딫혀본 상황이였다.
붙인 문자를 지워내는 방법이 있다.
(다른 해법을 찾게 되어 풀이에서 쓰진 않았다)
answer = ''
for i in my_string:
if i not in answer:
answer += i
answer = answer.rstrip(i)
이렇게 rstrip(i)로 방금 추가한 그녀석을 맨뒤에서 다시 지울 수 있다.
좋다기 보다는, 방법이 없진 않다라는 느낌이다.
문자열을 떼낸다는 거 자체가 별로 좋은 상황은 아니라고 느껴진다.
다만, 앞으로 혹시 써먹을 일이 생길지도 모르겠다.
결론, 문자열 가공은 직관적이고 쉬우니까 기본만 잘 기억하자.
문자열도 리스트처럼 그만의 특이함이 있는 것 같다.