Python provides two primary ways to read input: the built-in input() function and sys.stdin.readline(). For interactive scripts and everyday use, input() is clean and convenient. For competitive programming, batch processing, and any scenario involving large volumes of input, sys.stdin.readline() offers a significant performance advantage, often running 4 to 10 times faster.
This guide explains how each method works, when to use which, and the common patterns that make sys.stdin.readline() the standard choice in performance-sensitive contexts.
Using input(): Designed for Interactive Use
The input() function is designed for user-facing applications. It can display a prompt, waits for the user to type a line, and automatically strips the trailing newline before returning the result:
name = input("Enter your name: ")
age = int(input("Enter your age: "))
print(f"Hello {name}, you are {age} years old")Output (interactive session):
Enter your name: Alice
Enter your age: 30
Hello Alice, you are 30 years oldThis is clean and intuitive. The prompt appears, the newline is handled for you, and the returned string is ready to use immediately.
Using sys.stdin.readline(): Designed for Speed
sys.stdin.readline() reads directly from the input buffer with minimal overhead, but it keeps the trailing newline character in the returned string. You must handle that newline yourself:
import sys
line = sys.stdin.readline() # Includes '\n' at the end
clean_line = line.strip() # Remove the newline manually
number = int(sys.stdin.readline()) # int() ignores trailing whitespace automaticallyWhy sys.stdin.readline() Is Faster
The input() function performs additional work behind the scenes: it calls sys.stdout.write() to display the prompt (even if the prompt is empty), flushes the output buffer, and then processes the input through extra layers. sys.stdin.readline() skips all of this and reads directly from the standard input buffer.
import sys
import time
from io import StringIO
test_data = "123\n" * 1_000_000
sys.stdin = StringIO(test_data)
start = time.time()
for _ in range(1_000_000):
n = int(input())
time_input = time.time() - start
sys.stdin = StringIO(test_data)
start = time.time()
for _ in range(1_000_000):
n = int(sys.stdin.readline())
time_readline = time.time() - start
sys.stdin = sys.__stdin__
print(f"input(): {time_input:.2f}s")
print(f"readline(): {time_readline:.2f}s")
print(f"Speedup: {time_input / time_readline:.1f}x")Typical Output:
input(): 1.85s
readline(): 0.42s
Speedup: 4.4xOn one million lines, the difference is substantial. In competitive programming, where time limits are tight and input can be very large, this speedup often determines whether a solution passes or gets a "Time Limit Exceeded" verdict.
The Competitive Programming Pattern
A widely used trick is to override the built-in input name with sys.stdin.readline. This gives you the speed benefit without changing any of your existing code that calls input():
import sys
input = sys.stdin.readline
n = int(input())
values = list(map(int, input().split()))For maximum speed, you can also buffer the output:
import sys
input = sys.stdin.readline
print = sys.stdout.write
result = 42
print(f"{result}\n")Reading Multiple Lines Efficiently
Reading n lines of integers
import sys
input = sys.stdin.readline
n = int(input())
numbers = [int(input()) for _ in range(n)]Reading space-separated values on a single line
import sys
input = sys.stdin.readline
values = list(map(int, input().split()))Reading a grid
import sys
input = sys.stdin.readline
n, m = map(int, input().split())
grid = [list(map(int, input().split())) for _ in range(n)]Reading pairs of values
import sys
input = sys.stdin.readline
n = int(input())
pairs = [tuple(map(int, input().split())) for _ in range(n)]Reading string values (strip is required)
import sys
input = sys.stdin.readline
n = int(input())
words = [input().strip() for _ in range(n)]Reading Until End of File (EOF)
When the number of input lines is not known in advance, you need to read until the input stream ends:
import sys
data = sys.stdin.read()
lines = data.strip().split('\n')
for line in sys.stdin:
process(line.strip())
while True:
line = sys.stdin.readline()
if not line: # Empty string means EOF
break
process(line.strip())The Trailing Newline Pitfall
The most common bug when switching to sys.stdin.readline() is forgetting that the trailing newline is preserved. This causes string comparisons to fail silently:
import sys
line = sys.stdin.readline()
print(line == "hello") # False!
print(repr(line)) # 'hello\n'
print(line.strip() == "hello") # TrueOutput:
False
'hello\n'
TrueQuick Reference
| Feature | input() |
sys.stdin.readline() |
|---|---|---|
| Prompt support | Yes | No |
| Trailing newline | Automatically removed | Kept in the returned string |
| Speed | Slower | 4 to 10x faster |
| Best for | Interactive scripts, user-facing apps | Batch processing, competitive programming |
| Newline handling | Not needed | Use .strip() for strings; int()/float() handle it automatically |
Summary
- Use
input()for interactive scripts and user-facing applications where prompts and convenience matter. - Switch to
sys.stdin.readline()when processing large amounts of input data, especially in competitive programming where the speed difference of 4 to 10x can determine whether your solution passes within the time limit. - When using
sys.stdin.readline(), remember to call.strip()on string values to remove the trailing newline, and consider overridinginput = sys.stdin.readlineat the top of your script to get the speed benefit without rewriting existing code.