(Python)input()과 sys.stdin.readline()

실험하는 코더·2024년 2월 14일
0

python 입문

목록 보기
3/7

오늘의 글은 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
'''

개행문자포함2
출력값은 위의 디버깅 결과를 보시면 아시다시피 readline의 개행문자가 남아있어서 줄이 바뀌어 출력이 되는 것을 확인할 수 있었습니다.

그래서 가끔 알고리즘 문제를 풀다보면 코드는 정말 괜찮은데 에러가 나는 경우를 확인할 경우, 개행문자가 붙어서 문제가 생기게 되는데 이때는 strip()함수를 통해 해결하시면 되겠습니다.

오늘의 결론

  1. input()은 sys.stdin.readline()과 비교해서 prompt message를 출력하고, 개행 문자를 삭제한 값을 리턴할 뿐만 아니라 문자열을 하나씩 저장하기 때문에 여러 줄을 받아오는 과정은 느리다.
  2. 하지만 한줄만 입력을 받는 상황이면 개행문자를 제거를 직접해주기 때문에 더 빠른 작업이 가능하다.
  3. readline을 쓰다가 오류가 나는 경우 strip을 통해 개행 문자를 제거하고 사용!
  4. 블로그를 작성했으면 제때 올리기
profile
노베이스의 기록

0개의 댓글