Strings - Capitalize!
split()
의 인수에 공백 문자열을 주고 ''.join
을 써주면 다수의 공백도 그대로 보존된다는 걸 알게 된 문제.
문제 풀이
문제 해석
- 사람들의 여권 속 성과 이름을 받으면 첫 글자를 대문자로 처리하도록 요청받았다.
- full name을 담은 string, S를 한 줄로 입력받는다.
문제 풀이
이미 주어진 코드 해석
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| import math import os import random import re import sys
def solve(s):
if __name__ == '__main__': fptr = open(os.environ['OUTPUT_PATH'], 'w') s = input() result = solve(s) fptr.write(result + '\n') fptr.close()
|
- 온갖 모듈을 다 import하길래 여기에 낚여서 정규표현식을 쓰는 접근을 함…
OUTPUT_PATH
이건 또 뭔지 모르겟지만 일단 s에 할당한 인풋을 인수로 넣으면 대문자로 첫 글자를 바꾸어 반환해주는 함수를 만들어야 한다.
시행착오
- 가장 원시적으로는 for문을 하나하나 돌리면서 첫 글자인지 확인하는 if문을 쓰고
replace
메서드로 방법도 있지만 난 이제 그정도 수준은 졸업한 것 같다.
- 그러나 그보다 더 나은 대안도 딱히 떠오르지 않고 정규표현식으로 앞글자가 알파벳이 아니거나 처음 시작하는 글자이면 바꿔주는
re.sub
밖엔 생각이 나지 않았다.1 2 3 4 5 6
| def capitalize_matchobj(match_object): return match_object.group().upper()
def solve(s): sub_s = re.sub(r'(?<=\s)[a-z]|^[a-z]', capitalize_matchobj, s) return sub_s
|
- 그러다보니 이런 호러블한 코드가 나왔다. match object 처리를 해줘야하기 때문에 sub에 넣을 repl에 넣을 함수를 따로 정의하는 완전 비효율적인 접근… (아마 이거 잘 처리하는 방법이 있을텐데 지금으로서는 모르겠다)
- 그러던 중에
capitalize
라는 메서드가 있다는 것도 알게 되었지만, 여러 단어가 있어도 맨 첫 단어의 앞 글자만 대문자로 변환해주기 때문에 단어를 split으로 쪼개 capitalize한 후 다시 join해주었다.
- 분명 문제는 여권에 있는 이름이라고 했으면서 공백이 두개나 존재하는 이상한 case를 주어서 공백 두개 이상인 경우를 처리하지 못하고 discussions를 컨닝.
- 무림고수들이 정말 많아 겸손해졌다. 그 중의 몇몇 솔루션을 소개한다.
list comprehension 활용
1 2 3
| def solve(s): split_str = s.split(' ') return ' '.join([word.capitalize() for word in a_string])
|
split
을 할 때부터 공백으로 하면 공백들도 보존이 된다는 것을 이제야 깨달았다.
map 함수에 str 객체 메서드 활용
1 2
| def solve(s): return ' '.join(map(str.capitalize, s.split(' ')))
|
- capitalize 앞에만 대상 문자열을 넣을 수 있는 줄 알았는데 str에 메서드를 호출하면서 대상 문자열을 인수로 넣어줄 수도 있는 거였다.
- 이를 콜백함수로 넣은 map에 아까처럼 공백을 기준으로 split하여 한줄로 끝냈다.
느낀 점
- 한줄로 끝내는 끝판왕 앞에서 겸손해졌다.
str.capitalize
처럼 str이라는 객체에 메서드를 호출하는 방식도 잘 알아두어야겠다.
hanana1253문정동에서 코딩하는 하나나입니다.