I'm trying to do some of the code golf challenges, but they all require the input to be taken from
stdin. How do I get that in Python?
Here's from Learning Python:
import sys data = sys.stdin.readlines() print "Counted", len(data), "lines."
On Unix, you could test it by doing something like:
% cat countlines.py | python countlines.py Counted 3 lines.
On Windows or DOS, you'd do:
C:\> type countlines.py | python countlines.py Counted 3 lines.
There's a few ways to do it.
sys.stdin is a file-like object on which you can call functions
readlines if you want to read everything or you want to read everything and split it by newline automatically. (You need to
import sys for this to work.)
If you want to prompt the user for input, you can use
raw_input in Python 2.X, and just
input in Python 3.
If you actually just want to read command-line options, you can access them via the sys.argv list.
You will probably find this Wikibook article on I/O in Python to be a useful reference as well.
import sys for line in sys.stdin: print line
Python also has built-in functions
raw_input(). See the Python documentation under Built-in Functions.
name = raw_input("Enter your name: ") # Python 2.x
name = input("Enter your name: ") # Python 3
The answer proposed by others:
for line in sys.stdin: print line
is very simple and pythonic, but it must be noted that the script will wait until EOF before starting to iterate on the lines of input.
This means that
tail -f error_log | myscript.py will not process lines as expected.
The correct script for such a use case would be:
while 1: try: line = sys.stdin.readline() except KeyboardInterrupt: break if not line: break print line
From the comments it has been cleared that on python 2 only there might be buffering involved, so that you end up waiting for the buffer to fill or EOF before the print call is issued.
This will echo standard input to standard output:
import sys line = sys.stdin.readline() while line: print line, line = sys.stdin.readline()
Building on all the anwers using
sys.stdin, you can also do something like the following to read from an argument file if at least one argument exists, and fall back to stdin otherwise:
import sys f = open(sys.argv) if len(sys.argv) > 1 else sys.stdin for line in f: # Do your stuff
and use it as either
$ python do-my-stuff.py infile.txt
$ cat infile.txt | python do-my-stuff.py
$ python do-my-stuff.py < infile.txt
That would make your Python script behave like many GNU/Unix programs such as
import sys print sys.stdin.read().upper()
and check it with:
$ echo "Hello World" | python myFile.py
You can read from stdin and then store inputs into "data" as follows:
data = "" for line in sys.stdin: data += line
I had some issues when getting this to work for reading over sockets piped to it. When the socket got closed it started returning empty string in an active loop. So this is my solution to it (which I only tested in linux, but hope it works in all other systems)
import sys, os sep=os.linesep while sep == os.linesep: data = sys.stdin.readline() sep = data[-len(os.linesep):] print '> "%s"' % data.strip()
So if you start listening on a socket it will work properly (e.g. in bash):
while :; do nc -l 12345 | python test.py ; done
And you can call it with telnet or just point a browser to localhost:12345
The following chip of code will help you (it will read all of stdin blocking unto
EOF, into one string):
import sys input_str = sys.stdin.read() print input_str.split()
for line in sys.stdin:
I just tried it on python 2.7 (following someone else's suggestion) for a very large file, and I don't recommend it, precisely for the reasons mentioned above (nothing happens for a long time).
I ended up with a slightly more pythonic solution (and it works on bigger files):
with open(sys.argv, 'r') as f: for line in f:
Then I can run the script locally as:
python myscript.py "0 1 2 3 4..." # can be a multi-line string or filename - any std.in input will work
How do you read from stdin in Python?
I'm trying to do some of the code golf challenges, but they all require the input to be taken from stdin. How do I get that in Python?
sys.stdinexamples compatible with Python 2 and 3, Windows, Unix
You just need to
sys.stdin, for example, if you pipe data to stdin:
$ echo foo | python -c "import sys; print(sys.stdin.read())" foo
Say you have a file,
inputs.txt, we can accept that file and write it back out:
python -c "import sys; sys.stdout.write(sys.stdin.read())" < inputs.txt
Here's a complete, easily replicable demo, using two methods, the builtin function,
raw_input in Python 2), and
sys.stdin. The data is unmodified, so the processing is a non-operation.
To begin with, let's create a file for inputs:
$ python -c "print('foo\nbar\nbaz')" > inputs.txt
And using the code we've already seen, we can check that we've created the file:
$ python -c "import sys; sys.stdout.write(sys.stdin.read())" < inputs.txt foo bar baz
Here's the help on
sys.stdin.read from Python 3:
read(size=-1, /) method of _io.TextIOWrapper instance Read at most n characters from stream. Read from underlying buffer until we have n characters or we hit EOF. If n is negative or omitted, read until EOF.
raw_inputin Python 2)
The builtin function
input reads from standard input up to a newline, which is stripped (complementing
Thus, here's how you can use
input in Python 3 (or
raw_input in Python 2) to read from stdin - so we create a Python module we call stdindemo.py:
$ python -c "print('try:\n while True:\n print(input())\nexcept EOFError:\n pass')" > stdindemo.py
And let's print it back out to ensure it's as we expect:
$ python -c "import sys; sys.stdout.write(sys.stdin.read())" < stdindemo.py try: while True: print(input()) except EOFError: pass
input reads up until the newline and essentially strips it from the line.
input gets the end-of-file character, it raises EOFError, which we ignore and then exit from the program.
And on Linux/Unix, we can pipe from cat:
$ cat inputs.txt | python -m stdindemo foo bar baz
Or we can just redirect the file from stdin:
$ python -m stdindemo < inputs.txt foo bar baz
We can also execute the module as a script:
$ python stdindemo.py < inputs.txt foo bar baz
Here's the help on the builtin
input from Python 3:
input(prompt=None, /) 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.
Here we make a demo script using
sys.stdin. The efficient way to iterate over a file-like object is to use the file-like object as an iterator. The complementary method to write to stdout from this input is to simply use
$ python -c "print('import sys\nfor line in sys.stdin:\n sys.stdout.write(line)')" > stdindemo2.py
Print it back out to make sure it looks right:
$ python -c "import sys; sys.stdout.write(sys.stdin.read())" < stdindemo2.py import sys for line in sys.stdin: sys.stdout.write(line)
And redirecting the inputs into the file:
$ python -m stdindemo2 < inputs.txt foo bar baz
Golfed into a command:
$ python -c "import sys; sys.stdout.write(sys.stdin.read())" < inputs.txt foo bar baz
Since the file descriptors for
stdout are 0 and 1 respectively, we can also pass those to
open in Python 3 (not 2, and note that we still need the 'w' for writing to stdout).
If this works on your system, it will shave off more characters.
$ python -c "open(1,'w').write(open(0).read())" < inputs.txt baz bar foo
io.open does this as well, but the import takes a lot more space:
$ python -c "from io import open; open(1,'w').write(open(0).read())" < inputs.txt foo bar baz
One comment suggests
''.join(sys.stdin) but that's actually longer than sys.stdin.read() - plus Python must create an extra list in memory (that's how
str.join works when not given a list) - for contrast:
The top answer suggests:
import fileinput for line in fileinput.input(): pass
sys.stdin implements the file API, including the iterator protocol, that's just the same as this:
import sys for line in sys.stdin: pass
Another answer does suggest this. Just remember that if you do it in an interpreter, you'll need to do Ctrl-d if you're on Linux or Mac, or Ctrl-z on Windows (after Enter) to send the end-of-file character to the process. Also, that answer suggests
print(line) - which adds a
'\n' to the end - use
print(line, end='') instead (if in Python 2, you'll need
from __future__ import print_function).
The real use-case for
fileinput is for reading in a series of files.
PS I spent a lot of effort trying to make these demos work cross-platform. The Python is consistent, but the shell entries are not very flexible. However, making this accessible to people on Windows as well as Linux was important to me. Let me know if you have issues with Windows.
sys.stdin, but to read binary data on Windows, you need to be extra careful, because
sys.stdin there is opened in text mode and it will corrupt
\r\n replacing them with
The solution is to set mode to binary if Windows + Python 2 is detected, and on Python 3 use
import sys PY3K = sys.version_info >= (3, 0) if PY3K: source = sys.stdin.buffer else: # Python 2 on Windows opens sys.stdin in text mode, and # binary data that read from it becomes corrupted on \r\n if sys.platform == "win32": # set sys.stdin to binary mode import os, msvcrt msvcrt.setmode(sys.stdin.fileno(), os.O_BINARY) source = sys.stdin b = source.read()
I am pretty amazed no one had mentioned this hack so far:
python -c "import sys;print (''.join([l for l in sys.stdin.readlines()]))"
compatible with both python2 and python3
One option is to use input function as shown below. There is also raw_input method if you are not sure about the data type.
#!/usr/bin/env python number = input("Please enter a number : ") print("Entered number is %d" % number)
Running the program:
python test1.py Please enter a number : 55 Entered number is 55
The problem I have with solution
import sys for line in sys.stdin: print(line)
is that if you don't pass any data to stdin, it will block forever. That's why I love this answer: check if there is some data on stdin first, and then read it. This is what I ended up doing:
import sys import select # select(files to read from, files to write to, magic, timeout) # timeout=0.0 is essential b/c we want to know the asnwer right away if select.select([sys.stdin], , , 0.0): help_file_fragment = sys.stdin.read() else: print("No data passed to stdin", file=sys.stderr) sys.exit(2)