schritte - python[:




Wie liest du in Python von stdin? (13)

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 - Rufen Sie sys.stdin.read() auf, um alles zu lesen.
  • input(prompt) - übergeben Sie eine optionale Eingabeaufforderung zur Ausgabe, es liest von der Standardeingabe bis zum ersten Zeilenumbruch, den es entfernt. Sie müssten dies wiederholt tun, um mehr Zeilen zu erhalten, am Ende der Eingabe wird EOFError ausgelöst. (Wahrscheinlich nicht sehr gut zum Golfspielen.) In Python 2 ist das rawinput(prompt) .
  • open(0).read() - In Python 3 akzeptiert open 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 sys.stdin für das Golfen.
  • open('/dev/stdin').read() - ähnlich wie 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 sys.argv[1:] aufgelistet sind, oder stdin, falls nicht angegeben. Verwenden Sie wie ''.join(fileinput.input()) .

Sowohl sys als auch fileinput müssen fileinput importiert werden.

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

Sie müssen zum Beispiel nur aus sys.stdin read , wenn Sie Daten nach stdin sys.stdin :

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

Dateibeispiel

inputs.txt , Sie haben eine Datei, inputs.txt , können wir diese Datei akzeptieren und sie wieder inputs.txt :

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

Längere Antwort

Hier ist eine vollständige, leicht replizierbare Demo, die zwei Methoden verwendet: die eingebaute Funktion, input ( raw_input in Python 2 verwenden) 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 zu sys.stdin.read von 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.

Vordefinierte Funktion, input ( raw_input in Python 2)

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

So können Sie in Python 3 (oder raw_input in Python 2) input von stdin lesen - also erstellen wir ein Python-Modul namens 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

Auch hier liest sich die input bis zum Zeilenumbruch und entfernt sie 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 wenn die input das Dateiendezeichen erhält, wird EOFError ausgelöst, was ignoriert und dann vom Programm beendet wird.

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 zu den integrierten input von 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 sys.stdin 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 ergänzende Methode, von dieser Eingabe in stdout zu schreiben, besteht darin, einfach 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 0 und 1 sind, können wir auch diejenigen übergeben, open in Python 3 open (nicht 2, und beachten Sie, dass wir immer noch das 'w' zum 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

Python 2's io.open tut dies auch, aber der Import benötigt 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 tatsächlich länger als sys.stdin.read () - plus Python muss eine zusätzliche Liste im Speicher erstellen (so funktioniert str.join wenn man keine Liste erhält) - für den Kontrast :

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

Die beste Antwort lautet:

import fileinput

for line in fileinput.input():
    pass

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

import sys

for line in sys.stdin:
    pass

Eine andere Antwort deutet darauf hin. Denken Sie daran, dass Sie, wenn Sie es in einem Interpreter machen, Ctrl- d ausführen müssen, wenn Sie Linux oder Mac verwenden, oder Ctrl -z unter Windows (nach Enter ), um das Dateiende-Zeichen an das Symbol zu senden verarbeiten. Diese Antwort schlägt auch print(line) - was ein '\n' zum Ende hinzufügt - benutze stattdessen print(line, end='') (wenn du in Python 2 from __future__ import print_function ).

Der wirkliche Anwendungsfall für den fileinput ist das Lesen einer Reihe von Dateien.

Ich versuche, einige der Herausforderungen beim Codegolf zu stdin , aber sie alle erfordern, dass der Input von der stdin . Wie bekomme ich das in Python?


Aufbauend auf alle Antworten mit sys.stdin können Sie auch Folgendes tun, um aus einer Argumentdatei zu lesen, wenn mindestens ein Argument existiert, und andernfalls auf stdin zurückzugreifen:

import sys
f = open(sys.argv[1]) if len(sys.argv) > 1 else sys.stdin    
for line in f:
#     Do your stuff

und benutze es als entweder

$ python do-my-stuff.py infile.txt

oder

$ cat infile.txt | python do-my-stuff.py

oder auch

$ python do-my-stuff.py < infile.txt

Das würde Ihr Python-Skript wie viele GNU / Unix-Programme wie cat , grep und sed aussehen lassen.


Das Problem habe ich mit Lösung

import sys

for line in sys.stdin:
    print(line)

Wenn Sie keine Daten an stdin übergeben, wird dies für immer blockiert. Deshalb liebe ich diese Antwort : überprüfen Sie zuerst, ob es Daten auf stdin gibt, und lesen Sie sie dann. Das habe ich getan:

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)[0]:
    help_file_fragment = sys.stdin.read()
else:
    print("No data passed to stdin", file=sys.stderr)
    sys.exit(2)

Der folgende Code-Code wird Ihnen helfen (er liest alle stdin-Blockierungen in EOF in eine Zeichenfolge):

import sys
input_str = sys.stdin.read()
print input_str.split()

Dies gibt die Standardeingabe an die Standardausgabe zurück:

import sys
line = sys.stdin.readline()
while line:
    print line,
    line = sys.stdin.readline()

Eine Möglichkeit besteht darin, die Eingabefunktion wie unten gezeigt zu verwenden. Wenn Sie sich bezüglich des Datentyps nicht sicher sind, gibt es auch die Methode raw_input.

#!/usr/bin/env python

number = input("Please enter a number : ")
print("Entered number is %d" % number)

Ausführen des Programms:

python test1.py

Please enter a number : 55
Entered number is 55

Referenz: http://www.python-course.eu/input.php


Hier ist von Learning Python :

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.

Ich bin ziemlich erstaunt, dass niemand diesen Hack bisher erwähnt hat:

python -c "import sys;print (''.join([l for l in sys.stdin.readlines()]))"

kompatibel mit Python2 und Python3


Lesen Sie von sys.stdin , aber um Binärdaten unter Windows zu lesen , müssen Sie besonders vorsichtig sein, da sys.stdin dort im Textmodus geöffnet ist und es \r\n durch \r\n ersetzen wird.

Die Lösung besteht darin, den Modus auf binär zu setzen, wenn Windows + Python 2 erkannt wird, und in Python 3 sys.stdin.buffer .

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()

Python hat auch die eingebauten Funktionen input() und raw_input() . Weitere Informationen finden Sie in der Python-Dokumentation unter Integrierte Funktionen .

Beispielsweise,

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

oder

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

Sie könnten das fileinput Modul verwenden:

import fileinput

for line in fileinput.input():
    pass

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


Versuche dies:

import sys

print sys.stdin.read().upper()

und überprüfe es mit:

$ echo "Hello World" | python myFile.py

n = int(raw_input())
for i in xrange(n):
    name, number = raw_input().split()






stdin