Frage Wie liest du in Python von stdin?


Ich versuche etwas zu tun Code Golf Herausforderungen, aber sie alle erfordern die Eingabe von entnommen werden stdin. Wie bekomme ich das in Python?


1171
2017-09-20 05:48


Ursprung


Antworten:


Du könntest das benutzen fileinput Modul:

import fileinput

for line in fileinput.input():
    pass

fileinput Durchläuft alle Zeilen in der Eingabe, die als Dateinamen in Befehlszeilenargumenten angegeben sind, oder die Standardeingabe, wenn keine Argumente angegeben sind.


801
2017-09-20 05:53



Es gibt ein paar Möglichkeiten, dies zu tun.

  • sys.stdin ist ein dateiähnliches Objekt, auf dem Sie Funktionen aufrufen können read oder readlines wenn Sie alles lesen wollen oder alles lesen wollen und automatisch nach Newline aufteilen. (Du brauchst import sys damit dies funktioniert.)

  • Wenn du möchtest prompt Der Benutzer für die Eingabe können Sie verwenden raw_input in Python 2.X und nur input in Python 3.

  • Wenn Sie nur Befehlszeilenoptionen lesen möchten, können Sie über die Befehlszeile darauf zugreifen sys.argv Liste.

Sie werden wahrscheinlich finden Dieser Wikibook Artikel über I / O in Python auch eine nützliche Referenz sein.


584
2017-07-20 10:30



import sys

for line in sys.stdin:
    print line

331
2018-03-03 19:05



Python hat auch eingebaute Funktionen input() und raw_input(). Siehe die Python-Dokumentation unter Eingebaute Funktionen.

Beispielsweise,

name = raw_input("Enter your name: ")   # Python 2.x

oder

name = input("Enter your name: ")   # Python 3

180
2017-09-30 09:08



Hier ist von Python lernen:

import sys
data = sys.stdin.readlines()
print "Counted", len(data), "lines."

Unter Unix können Sie es testen, indem Sie Folgendes tun:

% cat countlines.py | python countlines.py 
Counted 3 lines.

Unter Windows oder DOS würden Sie Folgendes tun:

C:\> type countlines.py | python countlines.py 
Counted 3 lines.

160
2017-07-30 04:10



Die Antwort von anderen vorgeschlagen:

for line in sys.stdin:
  print line

ist sehr einfach und pythonisch, aber es muss angemerkt werden, dass das Skript bis EOF warten wird, bevor es beginnt, auf den Zeilen der Eingabe zu iterieren.

Das bedeutet, dass tail -f error_log | myscript.py Zeilen werden nicht wie erwartet verarbeitet.

Das richtige Skript für einen solchen Anwendungsfall wäre:

while 1:
    try:
        line = sys.stdin.readline()
    except KeyboardInterrupt:
        break

    if not line:
        break

    print line

AKTUALISIEREN
Aus den Kommentaren wurde klar, dass auf Python 2 nur die Pufferung beteiligt sein könnte, so dass Sie warten müssen, bis der Puffer gefüllt oder EOF ist, bevor der Druckaufruf ausgegeben wird.


85
2017-08-09 16:31



Wie liest du in Python von stdin?

Ich versuche, einige der Herausforderungen beim Codegolf zu lösen, aber sie alle erfordern, dass der Input von der Standardeingabe übernommen wird. Wie bekomme ich das in Python?

Sie können verwenden:

  • sys.stdin - Ein dateiähnliches Objekt - Aufruf sys.stdin.read() um alles zu lesen.
  • input(prompt) - Übergeben Sie es eine optionale Eingabeaufforderung, es liest von stdin bis zum ersten Zeilenumbruch, die es auszieht. Sie müssten dies wiederholt tun, um mehr Zeilen zu erhalten, am Ende der Eingabe wird EOFError ausgelöst. (Wahrscheinlich nicht großartig zum Golfen.) In Python 2 ist das so rawinput(prompt).
  • open(0).read() - In Python 3 open akzeptiert Dateideskriptoren (Ganzzahlen, die Betriebssystem-IO-Ressourcen darstellen) und 0 ist der Deskriptor von stdin. Es gibt ein dateiähnliches Objekt wie sys.stdin - wahrscheinlich die beste Wahl für Golfspieler.
  • open('/dev/stdin').read() - ähnlich zu open(0), funktioniert auf Python 2 und 3, aber nicht auf Windows (oder auch Cygwin).
  • fileinput.input() - gibt einen Iterator über Zeilen in allen Dateien zurück, die in aufgelistet sind sys.argv[1:]oder stdin wenn nicht gegeben. Verwenden Sie wie ''.join(fileinput.input()).

Beide sys und fileinput muss natürlich importiert werden.

Schnell sys.stdin Beispiele, die mit Python 2 und 3, Windows, Unix kompatibel sind

Du musst es nur tun read von sys.stdinWenn Sie beispielsweise Daten an stdin übergeben:

$ echo foo | python -c "import sys; print(sys.stdin.read())"
foo

Dateibeispiel

Angenommen, Sie haben eine Datei, inputs.txtWir können diese Datei akzeptieren und sie wieder ausschreiben:

python -c "import sys; sys.stdout.write(sys.stdin.read())" < inputs.txt

Längere Antwort

Hier ist eine vollständige, leicht replizierbare Demo mit zwei Methoden, der eingebauten Funktion, input (benutzen raw_input in Python 2) und sys.stdin. Die Daten sind nicht modifiziert, so dass die Verarbeitung keine Operation ist.

Lassen Sie uns zunächst eine Datei für Eingaben erstellen:

$ python -c "print('foo\nbar\nbaz')" > inputs.txt

Mithilfe des bereits angezeigten Codes können wir überprüfen, ob wir die Datei erstellt haben:

$ python -c "import sys; sys.stdout.write(sys.stdin.read())" < inputs.txt 
foo
bar
baz

Hier ist die Hilfe auf sys.stdin.read aus 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.

Eingebaute Funktion, input (raw_input in Python 2)

Die eingebaute Funktion input liest von der Standardeingabe bis zu einer Zeilenumbruchzeile, die entfernt wird (Ergänzung) print, die standardmäßig eine neue Zeile hinzufügt.) Dies geschieht, bis es EOF (End Of File) erhält, an welchem ​​Punkt es ausgelöst wird EOFError.

So, hier ist, wie Sie verwenden können input in Python 3 (oder raw_input in Python 2) von stdin lesen - so erstellen wir ein Python-Modul stdindemo.py:

$ python -c "print('try:\n    while True:\n        print(input())\nexcept EOFError:\n    pass')" > stdindemo.py 

Und lasst es uns ausdrucken, um sicherzustellen, dass es so ist, wie wir es erwarten:

$ python -c "import sys; sys.stdout.write(sys.stdin.read())" < stdindemo.py 
try:
    while True:
        print(input())
except EOFError:
    pass

Nochmal, input liest bis zum Zeilenumbruch und entfernt es im Wesentlichen von der Zeile. print Fügt einen Zeilenumbruch hinzu. Während also beide die Eingabe ändern, werden ihre Änderungen abgebrochen. (Sie sind also im Wesentlichen das Komplement jedes anderen.)

Und wann input Ruft das Dateiende-Zeichen ab, es löst EOFError aus, das wir ignorieren und dann aus dem Programm beenden.

Und unter Linux / Unix können wir von cat:

$ cat inputs.txt | python -m stdindemo
foo
bar
baz

Oder wir können die Datei einfach von stdin umleiten:

$ python -m stdindemo < inputs.txt 
foo
bar
baz

Wir können das Modul auch als Skript ausführen:

$ python stdindemo.py < inputs.txt 
foo
bar
baz

Hier ist die Hilfe zum Einbau input aus 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.

sys.stdin

Hier machen wir ein Demo-Skript mit sys.stdin. Die effiziente Möglichkeit, über ein dateiähnliches Objekt zu iterieren, besteht darin, das dateiähnliche Objekt als Iterator zu verwenden. Die komplementäre Methode, von dieser Eingabe in stdout zu schreiben, ist einfach zu verwenden sys.stdout.write:

$ python -c "print('import sys\nfor line in sys.stdin:\n    sys.stdout.write(line)')" > stdindemo2.py

Drucken Sie es aus, um sicherzustellen, dass es richtig aussieht:

$ python -c "import sys; sys.stdout.write(sys.stdin.read())" < stdindemo2.py 
import sys
for line in sys.stdin:
    sys.stdout.write(line)

Und die Eingaben in die Datei umleiten:

$ python -m stdindemo2 < inputs.txt
foo
bar
baz

Golfen in einen Befehl:

$ python -c "import sys; sys.stdout.write(sys.stdin.read())" < inputs.txt
foo
bar
baz

Dateideskriptoren zum Golfen

Da die Dateideskriptoren für stdin und stdout sind 0 und 1, wir können diese auch weitergeben open in Python 3 (nicht 2, und beachten Sie, dass wir immer noch das 'w' für das Schreiben in stdout benötigen).

Wenn dies auf Ihrem System funktioniert, werden mehr Zeichen entfernt.

$ python -c "open(1,'w').write(open(0).read())" < inputs.txt
baz
bar
foo

Pythons 2 io.open tut dies auch, aber der Import braucht viel mehr Platz:

$ python -c "from io import open; open(1,'w').write(open(0).read())" < inputs.txt 
foo
bar
baz

Andere Kommentare und Antworten ansprechen

Ein Kommentar suggeriert ''.join(sys.stdin) aber das ist eigentlich länger als sys.stdin.read () - plus Python muss eine zusätzliche Liste im Speicher erstellen (so str.join funktioniert, wenn keine Liste vergeben wurde - für den Kontrast:

''.join(sys.stdin)
sys.stdin.read()

Die beste Antwort lautet:

import fileinput

for line in fileinput.input():
    pass

Aber seit sys.stdin implementiert die Datei-API, einschließlich des Iterator-Protokolls, das genau so ist:

import sys

for line in sys.stdin:
    pass

Eine andere Antwort tut schlage das vor. Denken Sie daran, wenn Sie es in einem Dolmetscher tun, müssen Sie tun Strg-d wenn Sie auf Linux oder Mac sind, oder Strg-z auf Windows (nach Eingeben) um das Dateiendezeichen an den Prozess zu senden. Auch diese Antwort suggeriert print(line) - Das fügt a hinzu '\n' bis zum Ende - verwenden print(line, end='') stattdessen (wenn Sie in Python 2 benötigen from __future__ import print_function).

Der wahre Anwendungsfall für fileinput ist zum Lesen in einer Reihe von Dateien.


49
2017-07-29 15:04