88

I want to write a program that gets multiple line input and work with it line by line. Why isn't there any function like raw_input in Python 3?

input does not allow the user to put lines separated by newline (Enter). It prints back only the first line.

Can it be stored in a variable or even read it to a list?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
MaciejPL
  • 1,017
  • 2
  • 9
  • 16

5 Answers5

100

raw_input can correctly handle the EOF, so we can write a loop, read till we have received an EOF (Ctrl-D) from user:

Python 3

print("Enter/Paste your content. Ctrl-D or Ctrl-Z ( windows ) to save it.")
contents = []
while True:
    try:
        line = input()
    except EOFError:
        break
    contents.append(line)

Python 2

print "Enter/Paste your content. Ctrl-D or Ctrl-Z ( windows ) to save it."
contents = []
while True:
    try:
        line = raw_input("")
    except EOFError:
        break
    contents.append(line)
Raj
  • 3
  • 2
xiaket
  • 1,903
  • 1
  • 14
  • 8
  • 4
    Good answer. To answer the OP's question regarding Python 3, replace `raw_input("")` with `input()` and change the `print` statement to use brackets – Alastair McCormack Sep 16 '16 at 10:23
  • And what happens when the user writes some stuff on the line but instead of hitting enter for a newline, they press ctrl-d to trigger the EOFError? From my testing, it results in the last element in `contents` having its last character trimmed. – 2rs2ts May 09 '17 at 20:23
  • I would suppose you have used double Ctrl-D(which is not really the case we are discussing here) since a single Ctrl-D cannot trigger the EOFError in a non-empty line. – xiaket Jun 20 '17 at 12:20
  • In PyDev, pressing Ctrl-D to end the input does not work properly. – Stevoisiak Nov 02 '17 at 15:30
  • Using exceptions for control flow is not recommended in many languages and many programmers adopt the idiom 'use exceptions only in exceptional circumstances' (ie not for 'normal' behaviour). It seems to be more common in python. For more discussion, here's a stack exchange question discussing the tradeoffs: https://softwareengineering.stackexchange.com/questions/351110/are-exceptions-for-flow-control-best-practice-in-python – MattCochrane Mar 12 '23 at 06:29
78

In Python 3.x the raw_input() of Python 2.x has been replaced by input() function. However in both the cases you cannot input multi-line strings, for that purpose you would need to get input from the user line by line and then .join() them using \n, or you can also take various lines and concatenate them using + operator separated by \n

To get multi-line input from the user you can go like:

no_of_lines = 5
lines = ""
for i in xrange(no_of_lines):
    lines+=input()+"\n"

print(lines)

Or

lines = []
while True:
    line = input()
    if line:
        lines.append(line)
    else:
        break
text = '\n'.join(lines)
AMGMNPLK
  • 1,974
  • 3
  • 11
  • 22
ZdaR
  • 22,343
  • 7
  • 66
  • 87
24

input(prompt) is basically equivalent to

def input(prompt):
    print(prompt, end='', file=sys.stderr, flush=True)
    return sys.stdin.readline()

You can read directly from sys.stdin if you like.

lines = sys.stdin.readlines()

lines = [line for line in sys.stdin]

five_lines = list(itertools.islice(sys.stdin, 5))
    

The first two require that the input end somehow, either by reaching the end of a file or by the user typing Control-D (or Control-Z in Windows) to signal the end. The last one will return after five lines have been read, whether from a file or from the terminal/keyboard.

Community
  • 1
  • 1
chepner
  • 497,756
  • 71
  • 530
  • 681
  • 3
    `[line.splitlines() for line in sys.stdin]` removes the carriage returns. – Nuno André Oct 03 '16 at 14:59
  • 1
    This solution works best if want to pipe data to Python, i.e. `printf "line1\nline2\n" | python -c 'import sys; print(list(sys.stdin))'` or `python -c 'import sys; print(list(sys.stdin))' <<< "line1\nline2\n"` will both print `['line1\n', 'line2\n']`. – Czechnology Nov 05 '20 at 10:51
  • 1
    This is the answer to OPs question. And it is awesome. There is probably a way to implement a custom Quit command instead of forcing users to unintuitively hit ctrl-d. I probably won't be figuring that out, but if someone else wants to........ – DonkeyKong Nov 20 '20 at 13:58
  • @DonkeyKong Ctrl-d isn't that unintuitive if you truly understand what it means to read from a *file*. If your use case is for input that is terminated by a specific command, your program *shouldn't* simply read from `sys.stdin`. – chepner Nov 20 '20 at 14:01
  • 1
    If your code is really reading to the end of a file, it means just that: read until there's nothing more to read, not read until it reads a special value. Control-D is the (terminal-specific) way to indicate the end of the "file" represented by your keyboard input. – chepner Nov 20 '20 at 14:30
  • Or put another way, it's not your program's job to provide an alternate way of closing the input file. – chepner Nov 20 '20 at 14:32
  • @chepner I want to be able to write a query for a sqlite db on the command line. That gets really painful when you can't edit the preceding lines as you go. Ctrl + D is not a terrible exit, by any means, I just think there could be a better method where users are concerned. Could be wrong, though. It's my first day using this method. Thank you for this brilliant solution. It really needs MUCH more exposure. Seemingly ever single Python blogger has no idea this can be done. Google couldn't find any references even when searching for it explicitly. – DonkeyKong Nov 20 '20 at 20:21
  • There are: write the query in the editor of your choice, the redirect the saved file. Standard input isn't *supposed* to be a convenient interactive environment. – chepner Nov 20 '20 at 20:32
  • @chepner the database is designed entirely using the sqlite2 package. It's corporate so an editor would need to be approved and probably purchased. There is no editor. I will maybe make a GUI one day, but until then, this will be super useful!! – DonkeyKong Nov 20 '20 at 20:56
-1

Use the input() built-in function to get a input line from the user.

You can read the help here.

You can use the following code to get several line at once (finishing by an empty one):

while input() != '':
    do_thing
maggick
  • 1,362
  • 13
  • 23
-3
no_of_lines = 5
lines = ""
for i in xrange(5):
    lines+=input()+"\n"
    a=raw_input("if u want to continue (Y/n)")
    ""
    if(a=='y'):
        continue
    else:
        break
    print lines
Michael Dorner
  • 17,587
  • 13
  • 87
  • 117
  • 3
    Welcome to SO :) It's always better to add an explanation to the code you're posting as an answer, so that it will helps visitors understand why this is a good answer. – abarisone Jul 05 '16 at 06:18
  • This is my solution: def MultylineInput(): print("Enter/Paste your content. 'Ctrl-Z' to save it.") lines = [] while True: try: line = input() + '\n' if line: lines.append(line) except EOFError: break text = '\n'.join(lines) return text – E.F. Lucas Feb 08 '23 at 11:55