What is the difference between input() and sys.stdin?
Asked Answered
S

2

9

I am new to python and trying some coding problems online. i come across sys.sdnin a lot for accepting input. I would like to know how input() and sys.stdin differs in action?

Strega answered 8/4, 2015 at 23:21 Comment(4)
What's unclear in the documentation?Swaraj
difference between sys.stdin and input()Strega
Clearly there are lots of differences, because they are two completely different things, you can see that with just a glance at the docs, not saying anything about actually reading it. So, instead of repeating your extremely vague question (yes, we can read), please explain more precisely what do you find confusing.Swaraj
This question is interesting. It aims at understanding the full difference between input() and sys.stdin, how they differ, and why the one or the other are used for exactly the same thing (reading data) in different programming competitions such as Codingame, HackerRank, Battle Dev. This is something that is definitely not mentioned in the documentation, and that I too would like to see clarified.Kelsy
K
4

Clarification through Code Examples

I've been asking myself the same question, so I came up with these two snippets, which clarify how sys.stdin and input() differ by emulating the latter with the former:

import sys

def my_input(prompt=''):
  print(prompt, end='') # prompt with no newline
  for line in sys.stdin:
    if '\n' in line: # We want to read only the first line and stop there
      break
  return line.rstrip('\n')

Here is a more condensed version:

import sys

def my_input(prompt=''):
  print(prompt, end='')
  return sys.stdin.readline().rstrip('\n')

Both these snippets differ from the input() function in that they do not detect the End Of File (see below).

Clarification through Documentation

This is how the official documentation describes the function input():

input([prompt])

If the prompt argument is present, it is written to standard output without a trailing newline. The function then reads a line from input, converts it to a string (stripping a trailing newline), and returns that. When EOF is read, EOFError is raised.

And here's how sys.stdin is described:

sys.stdin

File object used by the interpreter for standard input.
stdin is used for all interactive input (including calls to input());
These streams (sys.stdin, sys.stdout and sys.stderr) are regular text files like those returned by the open() function. [...]

So whereas input() is a function, sys.stdin is an object (a File object). As such, it has a number of attributes, which you can explore in the interpreter, with:

> dir(sys.stdin)

['_CHUNK_SIZE',
 '__class__',
 '__del__',
 '__delattr__',
 '__dict__',
 '__dir__',

  ...

 'truncate',
 'writable',
 'write',
 'write_through',
 'writelines']

and which you can display individually, for instance:

> sys.stdin.mode
r

It also has methods, such as readline(), which "reads a single line from the file; a newline character (\n) is left at the end of the string, and is only omitted on the last line of the file if the file doesn’t end in a newline. This makes the return value unambiguous; if f.readline() returns an empty string, the end of the file has been reached, while a blank line is represented by '\n', a string containing only a single newline." (1)

Full implementation

This last method allows us to fully emulate the input() function, including its EOF Exception error:

def my_input(prompt=''):
  print(prompt, end='')
  line = sys.stdin.readline()
  if line == '': # readline() returns an empty string only if EOF has been reached
    raise EOFError('EOF when reading a line')
  else:
    return line.rstrip('\n')
Kelsy answered 28/11, 2020 at 9:33 Comment(0)
E
1

Here's something to get you started:

The builtin function input reads a line of input from the standard input stream, optionally with a message prompt. Be careful with the prompt, though, because the result of:

result = input('Do you want to do whatever? ')  ## doesn't work how you'd expect
if result.lower() in ('y', 'ye', 'yes', 'yup', 'ya'):
    do_whatever()
    ...
else:
    do_something_else()
    ...

..will include the prompt string as well (and so will never be equal to 'y'/'yes'/etc). In my opinion, it is better to print the prompt string first and then call input with no args, like so:

print('Do you want to do whatever?')
result = input()  ## notice that there is no prompt string passed to input()
if result.lower() in ('y', 'ye', 'yes', 'yup', 'ya'):
    do_whatever()
    ...
else:
    do_something_else()
    ...

So, to recap, the builtin function input reads input from the standard input stream (sys.stdin), and the builtin function print prints output to the standard output stream (sys.stdout). There's a third one as well, the standard error stream (sys.stderr), to which unhandled exceptions get printed.

Usually, you don't have to worry about it too much. It's just when building IDEs and frameworks and such.

Embrace answered 15/4, 2015 at 13:18 Comment(3)
"will include the prompt string as well" <- I'm not sure what you mean here, if I test this with something like x = input('here');print(x) I don't get 'here' output to the interpreter unless that's what I enter at the prompt. Whereas the way I'm reading what you've written I should infact get the output of 'here' as well as whatever I enter... cheersAkeyla
-1. This is not a barrage of downvotes on your answer. It's just the fact that this answer is not correct. The prompt never gets included into what the function input() returns.Kelsy
if I test this with something like x = input('here');print(x) I don't get 'here' output to the interpreter unless that's what I enter at the prompt. Whereas the way I'm reading what you've written I should infact get the output of 'here' as well as whatever I enter... cheersVicar

© 2022 - 2024 — McMap. All rights reserved.