오늘의 글은 input과 readline의 차이에 대해 다뤄보려고 합니다.
(글을 이주전에 작성하고 아직 안올렸더라구요...그래서 내용을 좀 추가했습니다.)
처음에는 백준10951 A+B-4를 풀면서 이것저것 시도중에 input을 받아오는 방법에 대략적으로 알았는데 이제는 조금더 자세히 알게되어 그 시절(3주전?)보다 내용을 추가해서 적게 되었습니다.
또, 정의부터 시작할 것이지만 이번에는 둘의 공식 문서 내용을 참고합시다.
help(input)
input(prompt='', /)
Read a string from standard input. The trailing newline is stripped.
The prompt string, if given, is printed to standard output without a
trailing newline before reading input.
If the user hits EOF (*nix: Ctrl-D, Windows: Ctrl-Z+Return), raise EOFError.
On *nix systems, readline is used if available.
import sys
help(sys.stdin)
readline(self, size=-1, /)
| Read until newline or EOF.
|
| Returns an empty string if EOF is hit immediately.
|
공식문서는 이렇게 영어로 둘의 정의가 적혀있는데, 둘다 새로운 줄을 받아오는데 사용하는 함수입니다.
하지만 여기 내용을 보면 EOF(End Of File)에 대해 다르게 다루고 있습니다.
보시는 바와 같이 input을 사용하면 EOF에 도달시, 즉 받는 데이터가 더이상 없는 경우 EOF error가 발생하지만, readline의 경우 빈 문자열로 인식하게 됩니다.
이 차이로 인해 위의 백준10951 문제를 해결할 경우,
무한 반복문을 이용하여 데이터를 받아 오면서 input은 EOF Error를 발생하기 때문에 이를 해결하기 위해 except 조건을 걸어주어야 정상동작이 가능해지고 readline은 그렇지 않아도 동작을 할 수 있다는 것을 알 수 있습니다.
원래 적고 싶었던 내용은 여기까지였으나, 이제 백준을 열심히 풀고 있는 저에게 readline은 시간초과를 안나게 하는 중요한 역할을 하고 있습니다.
실제로 백준 1874 스택수열 문제를 해결하는 과정에서 실수로
import sys
input = sys.stdin.readline의 문구를 지웠더니 112ms로 해결 가능한 문제가 3900ms가 걸리는 매우 유의미한 숫자 차이를 보였습니다.
그러면 왜 readline은 여러 줄의 input을 받아올때 빠른가? 이 점을 중점적으로 공부해봤습니다.
그 이유는 위의 공식문서내용에서도 알수 있듯이 둘이 input값을 받아올 때 차이가 있습니다.
input()은 prompt문구와 개행 문자를 제거해서(newline is stripped) 결과값을 저장하고 문자열을 하나씩 입력 받아와서 저장하지만
sys.stdin.readline은 개행문자까지 같이 저장하는 구조이기 때문에
따라서 연산이 추가된 input()의 경우가 더 오래걸리게 된다는 것을 추론할 수 있습니다.
그럼 프롬프트가 뭔지 간략하게 보여주자면,
# 프롬프트문구는 이런것
A= input("Prompt는 여기에 쓰인 문구 입니다.") #Prompt는 여기에 쓰인 문구 입니다. a(입력)
print(A) # a
import sys
B = sys.stdin.readline() #b (입력)
print(B) # b
input을 입력하기 전에 적혀있는 문구가 프롬프트입니다. 그 이후 각각 a,b와 입력을 해보고 출력을 하게 된다면 출력 결과는 그냥 저희가 단순히 입력한 a,b로 나오게 되는것을 확인할 수 있습니다. 하지만 이 과정을 디버깅해보면 아래 그림과 같이 보입니다.
보시는 것과 같이 input()은 prompt가 제거된 값이 저장되어 있고,
stdin.readline()은 개행문자까지 같이 저장되는 것을 확인할 수 있습니다.
그래서 이 형태를 보고 하나의 실험을 해보았습니다. 입력받은 B와 A를 합친 C를 출력하면 어떻게 될까요?
A= input("Prompt는 여기에 쓰인 문구 입니다.") # a입력
print(A)
import sys
B = sys.stdin.readline() # b입력
C= B + A
print(C)
'''
출력값
b
a
'''
출력값은 위의 디버깅 결과를 보시면 아시다시피 readline의 개행문자가 남아있어서 줄이 바뀌어 출력이 되는 것을 확인할 수 있었습니다.
그래서 가끔 알고리즘 문제를 풀다보면 코드는 정말 괜찮은데 에러가 나는 경우를 확인할 경우, 개행문자가 붙어서 문제가 생기게 되는데 이때는 strip()함수를 통해 해결하시면 되겠습니다.