python

[Troubleshooting] sys.stdin.readline() 꼭 개행문자 제거하자!

jooyeongmee 2023. 5. 22. 15:52

문제상황:

다음과 같이 코드를 작성했을 때 출력결과가 이상하게 줄바꿈이 자꾸 되는 것이다!!

for key, value in sorted(files.items()):
	print(key, str(value))

출력결과

시도

원인을 파악하려고 몇가지 방법을 시도해봤다

  • print문 변경 ---> 결과 똑같음,,
print(key + " " + str(value))
print("{} {}".format(key, str(value)))
  • print문 뒤에 end="" 추가
print(key, str(value), end="")

출력결과

흠.. 아무래도 key 값을 출력할 때만 줄바꿈이 들어가는 것 같다..??

  • 확인해보자!
for key, value in sorted(files.items()):
    print("===" + str(key) + "====")

출력결과

역시나 dictionary에서 key 값을 가져올 때 자동으로 줄바꿈이 들어가 있는 것 같다. 그럼 줄바꿈을 빼고 출력해보자!

 

해결:

for key, value in sorted(files.items()):
    print(key.strip(), str(value))

출력결과:

잘 나온다!! 끄읏

 

 

+++++++

다시 찾아보니 dictionary에서 가져올 때 개행문자가 들어가는 것이 아니라 애초에 dictionary에서 넣을 때부터 개행문자가 들어가 있었다..

files = {}
for i in range(num):
    name, ext = sys.stdin.readline().split('.')
    print("====" + ext + "====")
    if ext in files.keys():
        files[ext] += 1
    else:
        files[ext] = 1

딕셔너리에 넣기 전 출력해서 확인해보니,, 역시나,, 하핳

진짜 원인: 백준 풀 때는 시간초과 때문에 반복문 안에서는 보통 input() 대신 sys.stdin.readline()을 사용하고 있었는데 sys.stdin.readline()는 한줄 단위로 입력 받기에 개행문자가 같이 입력 받아진다. 그래서 꼭 rstrip()이나 strip()을 사용하여 개행문자를 제거해야 하는데 오랜만에 백준 풀었더니 깜빡했다,, ㅎㅎ

 

최종 해결:

import sys

num = int(input())

files = {}
for i in range(num):
    name, ext = sys.stdin.readline().rstrip().split('.')
    if ext in files.keys():
        files[ext] += 1
    else:
        files[ext] = 1

for key, value in sorted(files.items()):
    print(key, str(value))

출력결과:

잘 나온다!! 하핳 오늘도 바보같은 실수를 해버렸넹


그런데 백준 제출해보니 조금 느린 것 같아서 개선을 해보았다.

version 1


아무래도 딕셔너리를 정렬하는 부분에서 시간을 잡아먹는 것 같았다. 그래서 정렬하는 부분을 리스트로 바꿔보았다1

import sys

num = int(input())

files = {}
file_list = []
for i in range(num):
    name, ext = sys.stdin.readline().rstrip().split('.')
    if ext in files.keys():
        files[ext] += 1
    else:
        files[ext] = 1
        file_list.append(ext)

file_list.sort()
for _ in file_list:
    print(_, files[_])

Version 2

오오 메모리 사용량도, 시간도 조금 줄었다! 그래도 여전히 안 좋아보인다,,


리스트를 굳이 사용하지 말고 기존에 딕셔너리의 items 를 찾아서 정렬하는 부분이 오래 걸렸던 것 같아서 그 부분을 key로만 정렬하고 value는 키로 가져오는 형식으로 바꿨다.

import sys

num = int(input())

files = {}
for i in range(num):
    name, ext = sys.stdin.readline().rstrip().split('.')
    if ext in files.keys():
        files[ext] += 1
    else:
        files[ext] = 1

for _ in sorted(files.keys()):
    print(_, files[_])

Version 3

조금 더 줄었다! 흠.. 근데 이젠 더 어떻게 바꿔야 할 지 모르겠다..

혹시나 이 글을 보고 계신다면 더 좋은 방법 있으면 알려주시면 감사하겠습니다:D

 

이젠 정말정말 끄읏~