input()과 sys.stdin.readline()의 차이
요즘 부쩍 많이 보이는 파이썬 질문 중에 테스트할 때는 input()을 쓰고 제출할 때에만 sys.stdin.readline()을 쓰는 코드가 종종 보입니다. 알아보니 Jupyter를 쓰시는 분들이 주로 그렇게 하는 것 같습니다 (저는 PyCharm을 써서 몰랐습니다.) Jupyter에는 sys.stdin.readline이 구현되어 있지 않아서 어쩔 수 없이 제출할 때와 코드를 달리해야 하는데, 그렇다면 둘의 차이를 확실하게 알고 사용해야 합니다.
물론 내부적으로도 뭔가 차이가 있겠지만, 일단 겉으로 드러나는 매우 중요한 차이점은 바로 sys.stdin.readline()은 매 줄의 끝에 있는 개행 문자를 포함하여 반환해준다는 것입니다. 예를 들어, 입력으로 abc를 치고 엔터를 쳤다면 이를 s = input()으로 받으면 s에 "abc"가 저장되겠지만, s = sys.stdin.readline()으로 받으면 "abc\n"이 저장됩니다.
이를 구분하지 않고 그대로 input = sys.stdin.readline으로 놓고 사용하면 여러 문제가 생깁니다. 위의 "abc\n"의 경우 len(s)를 하면 3이 아닌 4가 되고, for x in s: 를 하면 x는 'a', 'b', 'c', '\n' 이렇게 네 개의 문자에 대해 돌게 됩니다.
그렇기 때문에 제출할 때에만 input을 sys.stdin.readline으로 대체할 거라면 그냥 =으로 바로 대입하기보다는 다음과 같이 하여 끝의 개행 문자를 버리고 사용하는 것이 좋습니다.
input = lambda: sys.stdin.readline().rstrip()
https://ideone.com/ 등의 사이트에서 아래의 코드의 주석을 바꿔가면서 출력 결과를 비교해 보세요.
import sys
# input = sys.stdin.readline
input = lambda: sys.stdin.readline().rstrip()
s = input()
print(len(s))
for x in s:
print(ord(x))
또 한 가지 중요한 차이점은 input은 입력의 끝 (EOF)을 만났을 때 EOFError를 raise하지만 sys.stdin.readline은 에러를 발생시키지 않고 정상적으로 빈 문자열을 반환한다는 것입니다. 따라서 로컬에서 input으로 EOF를 처리한 코드를 그대로 sys.stdin.readline으로 바꾸면 제대로 처리되지 않을 가능성이 높습니다. 요즘에는 EOF를 직접 판단해야 하는 문제가 많이 없지만 옛날 문제들 중에는 이 때문에 고생하게 되는 경우가 종종 있으니 주의해야 합니다.