Wie lese ich von stdin?

Lesezeit: 12 Minuten

Benutzer-Avatar
Teherjan

Wie lese ich ab stdin? Etwas Code-Golf Herausforderungen erfordern den Einsatz stdin für die Eingabe.

Verwenden Sie die fileinput Modul:

import fileinput

for line in fileinput.input():
    pass

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

Notiz: line wird einen abschließenden Zeilenumbruch enthalten; um es zu entfernen line.rstrip().

  • was ist der unterschied zwischen input() und fileinput.input()?

    – Amir reza Riahi

    21. März 2021 um 10:51 Uhr

  • @AmirrezaRiahi input() liest eine einzelne Zeile von stdin, wohingegen fileinput.input() wird durchschleifen alle die Zeilen in der Eingabe, die als Dateinamen in Befehlszeilenargumenten angegeben sind, oder die Standardeingabe, wenn keine Argumente bereitgestellt werden

    – Boris Werchowskij

    8. April 2021 um 15:14 Uhr


  • Danke, dass Sie das gefragt haben. Ich steckte fest, als eine der fileinput.input()-Zeilen mein Befehlszeilen-Argument war, als ich nur stdin lesen wollte.

    – Sridhar Sarnobat

    13. Dezember 2021 um 4:20 Uhr

  • Warum nicht Eingabe verwenden? Andernfalls befinden Sie sich in einer for-Schleife, während ich nur eine Eingabe möchte.

    – Thorsten Stärk

    27. Januar um 6:50 Uhr

  • Wenn Sie die Zeilen als Liste haben möchten, können Sie sie verwenden list(fileinput.input())

    – Sturm_m2138

    7. Juli um 22:27 Uhr

Benutzer-Avatar
Mark Ruschakoff

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

  • sys.stdin ist ein dateiähnliches Objekt, für das Sie Funktionen aufrufen können read oder readlines wenn Sie alles lesen möchten oder alles lesen und automatisch durch Zeilenumbruch teilen möchten. (Du musst import sys damit das funktioniert.)

  • Wenn Sie wollen prompt den Benutzer für Eingaben, die Sie verwenden können raw_input in Python 2.X und einfach input in Python3.

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

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

  • Die dritte Option ist das, wonach ich gesucht habe, um die Eingabe bei code.golf zu verarbeiten

    – bobsbeenjamin

    9. Dezember 2020 um 1:34 Uhr

Benutzer-Avatar
Benutzer303110

import sys

for line in sys.stdin:
    print(line)

Beachten Sie, dass dies am Ende ein Zeilenumbruchzeichen enthält. Um den Zeilenumbruch am Ende zu entfernen, verwenden Sie line.rstrip() wie @brittohalloran sagte.

  • line.rstrip(‘\n’), andernfalls werden alle Leerzeichen gelöscht

    – Avp

    1. November 2018 um 21:22 Uhr


  • Woher wissen wir mit dieser Methode, wann der Eingabestrom endet? Ich möchte nach jeder Zeile ein Komma hinzufügen ausgenommen für die letzte Zeile.

    – süchtig

    18. Dezember 2018 um 7:28 Uhr

  • Ich erhalte: TypeError: ‘FileWrapper’-Objekt ist nicht iterierbar.

    – Diego Queiroz

    20. Januar 2019 um 20:39 Uhr

  • @avp damit wird nicht richtig umgegangen \r\n Zeilenenden

    – josch

    9. Juli 2019 um 8:22 Uhr

  • Eine andere Möglichkeit, zusätzliche Zeilenumbrüche am Ende zu entfernen, ist die Verwendung print(line, end='').

    – ks1322

    4. April 2021 um 13:24 Uhr

Benutzer-Avatar
Pat Notz

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

Zum Beispiel,

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

oder

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

Hier ist von Python lernen:

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

Unter Unix könnten 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.

  • Hier ist eine speichereffizientere (und vielleicht schnellere) Möglichkeit, Zeilen in Python zu zählen: print(sum(chunk.count('\n') for chunk in iter(partial(sys.stdin.read, 1 << 15), ''))). sehen wc-l.py

    – jfs

    16. November 2012 um 4:32 Uhr

  • Die Verwendung von cat hier ist überflüssig. Der korrekte Aufruf für Unix-Systeme ist python countlines.py < countlines.py.

    – istepaniuk

    17. November 2015 um 11:14 Uhr

  • “Python lernen” ist falsch, wenn es Benutzer anweist, es zu verwenden readlines(). Dateiobjekte sollen durchlaufen werden, ohne alle Daten im Speicher zu materialisieren.

    – Russland muss Putin entfernen

    1. August 2016 um 14:56 Uhr


  • @istepaniuk In Bezug auf “Verwendung von Katze” finde ich Verwendung cat filespec | filters im Allgemeinen bequemer, wenn ich Befehlszeilenparameter an die Filter anpasse, da sie jedes Mal am Ende der Zeile stehen.

    – GeePokey

    18. Mai 2021 um 21:55 Uhr

  • @GeePokey Die Eingabeumleitung kann auch vorangestellt werden: < filespec filters

    – Panki

    27. Oktober 2021 um 13:38 Uhr

Benutzer-Avatar
Gemeinschaft

Wie liest man von stdin in Python?

Ich versuche, einige der Code-Golf-Herausforderungen zu meistern, aber alle erfordern, dass die Eingabe von stdin übernommen wird. Wie bekomme ich das in Python hin?

Sie können Folgendes verwenden:

  • sys.stdin – Ein dateiähnliches Objekt – Aufruf sys.stdin.read() alles zu lesen.
  • input(prompt) – Übergeben Sie ihm eine optionale Eingabeaufforderung zur Ausgabe, er liest von stdin bis zum ersten Zeilenumbruch, den er entfernt. Sie müssten dies wiederholt tun, um mehr Zeilen zu erhalten, am Ende der Eingabe wird EOFError ausgelöst. (Wahrscheinlich nicht gut zum Golfen.) In Python 2 ist dies rawinput(prompt).
  • open(0).read() – In Python 3 die eingebaute Funktion open akzeptiert Dateideskriptoren (Ganzzahlen, die E/A-Ressourcen des Betriebssystems darstellen), und 0 ist der Deskriptor von stdin. Es gibt ein dateiähnliches Objekt wie zurück sys.stdin – wahrscheinlich Ihre beste Wette zum Golfen. In Python 2 ist dies io.open.
  • open('/dev/stdin').read() – ähnlich zu open(0)funktioniert auf Python 2 und 3, aber nicht auf Windows (oder sogar Cygwin).
  • fileinput.input() – gibt einen Iterator über Zeilen in allen aufgelisteten Dateien zurück sys.argv[1:], oder stdin, falls nicht angegeben. Verwenden Sie wie ''.join(fileinput.input()).

Beide sys und fileinput müssen natürlich jeweils importiert werden.

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

Sie müssen nur read aus sys.stdinwenn Sie beispielsweise Daten an stdin weiterleiten:

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

Wir können das sehen sys.stdin ist im Standardtextmodus:

>>> import sys
>>> sys.stdin
<_io.TextIOWrapper name="<stdin>" mode="r" encoding='UTF-8'>

Datei Beispiel

Angenommen, Sie haben eine Datei, inputs.txtkönnen wir diese Datei akzeptieren und sie zurückschreiben:

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 (verwenden raw_input in Python 2) und sys.stdin. Die Daten sind unverändert, die Verarbeitung ist also keine Operation.

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

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

Und mit dem Code, den wir bereits gesehen haben, 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 sys.stdin.read aus Python3:

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

Die eingebaute Funktion input liest von der Standardeingabe bis zu einem Zeilenumbruch, der entfernt wird (ergänzend printdas standardmäßig einen Zeilenumbruch hinzufügt.) Dies geschieht, bis es EOF (End Of File) erhält, an welchem ​​Punkt es ausgelöst wird EOFError.

Also, hier ist, wie Sie verwenden können input in Python 3 (bzw raw_input in Python 2), um von stdin zu lesen – also erstellen wir ein Python-Modul, das wir stdindemo.py nennen:

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

Und lassen Sie uns es erneut 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

Wieder, input liest bis zum Zeilenumbruch und entfernt ihn im Wesentlichen von der Zeile. print fügt einen Zeilenumbruch hinzu. Während also beide die Eingabe ändern, werden ihre Änderungen aufgehoben. (Sie ergänzen sich also im Wesentlichen.)

Und wann input erhält das Dateiendezeichen, löst es EOFError aus, das wir ignorieren und dann das Programm verlassen.

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

$ 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 eingebauten input aus Python3:

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 erstellen wir ein Demo-Skript mit sys.stdin. Der effiziente Weg, ein dateiähnliches Objekt zu durchlaufen, besteht darin, das dateiähnliche Objekt als Iterator zu verwenden. Die ergänzende Methode, um 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 erneut 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

Golfte in einen Befehl:

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

Dateideskriptoren für Golf

Da die Dateideskriptoren für stdin und stdout 0 bzw. 1 sind, können wir diese auch weitergeben open in Python 3 (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 io.open tut dies auch, aber der Import nimmt viel mehr Platz ein:

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

Auf andere Kommentare und Antworten eingehen

Ein Kommentar legt nahe ''.join(sys.stdin) zum Golfen, aber das ist tatsächlich länger als sys.stdin.read() – außerdem muss Python eine zusätzliche Liste im Speicher erstellen (so str.join funktioniert, wenn keine Liste angegeben ist) – zum Kontrast:

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

Die oberste Antwort schlägt vor:

import fileinput

for line in fileinput.input():
    pass

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

import sys

for line in sys.stdin:
    pass

Eine andere Antwort tut schlage dies vor. Denken Sie nur daran, dass Sie dies tun müssen, wenn Sie es in einem Dolmetscher tun Strgd wenn Sie auf Linux oder Mac sind, oder Strgz unter Windows (nach Eintreten), um das Dateiendezeichen an den Prozess zu senden. Auch diese Antwort deutet darauf hin print(line) – was ein hinzufügt '\n' bis zum Ende – verwenden print(line, end='') stattdessen (in Python 2 benötigen Sie from __future__ import print_function).

Der eigentliche Anwendungsfall für fileinput dient zum Einlesen einer Reihe von Dateien.

  • Hier ist eine speichereffizientere (und vielleicht schnellere) Möglichkeit, Zeilen in Python zu zählen: print(sum(chunk.count('\n') for chunk in iter(partial(sys.stdin.read, 1 << 15), ''))). sehen wc-l.py

    – jfs

    16. November 2012 um 4:32 Uhr

  • Die Verwendung von cat hier ist überflüssig. Der korrekte Aufruf für Unix-Systeme ist python countlines.py < countlines.py.

    – istepaniuk

    17. November 2015 um 11:14 Uhr

  • “Python lernen” ist falsch, wenn es Benutzer anweist, es zu verwenden readlines(). Dateiobjekte sollen durchlaufen werden, ohne alle Daten im Speicher zu materialisieren.

    – Russland muss Putin entfernen

    1. August 2016 um 14:56 Uhr


  • @istepaniuk In Bezug auf “Verwendung von Katze” finde ich Verwendung cat filespec | filters im Allgemeinen bequemer, wenn ich Befehlszeilenparameter an die Filter anpasse, da sie jedes Mal am Ende der Zeile stehen.

    – GeePokey

    18. Mai 2021 um 21:55 Uhr

  • @GeePokey Die Eingabeumleitung kann auch vorangestellt werden: < filespec filters

    – Panki

    27. Oktober 2021 um 13:38 Uhr

Die von anderen vorgeschlagene Antwort:

for line in sys.stdin:
  print line

ist sehr einfach und pythonisch, aber es muss beachtet werden, dass das Skript bis EOF wartet, bevor es beginnt, die Eingabezeilen zu durchlaufen.

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

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 klargestellt, dass nur in Python 2 möglicherweise gepuffert wird, sodass Sie am Ende warten müssen, bis der Puffer gefüllt ist oder EOF, bevor der Druckaufruf ausgegeben wird.

  • Das for line in sys.stdin: Muster nicht warte auf EOF. Wenn Sie jedoch sehr kleine Dateien testen, werden die Antworten möglicherweise gepuffert. Testen Sie mit mehr Daten, um zu sehen, ob Zwischenergebnisse gelesen werden.

    – mb.

    11. Juli 2012 um 2:06 Uhr


  • Ich warte auf das Ende der Datei oder puffere, wenn ich bei Verwendung von Python 2.6.6 Eingaben aus einem Stream entgegennehme, aber mit 3.1.3 tue ich das nicht. Notiz print line wachte in 3.1.3 nicht auf, aber print(line) tut.

    – Strg-Alt-Entf

    7. September 2012 um 9:41 Uhr

  • mein Python 2.7.5 “for line in sys.stdin”, blockiert, bis EOF oder eine angemessene Datenmenge gepuffert wurde. Gut für Stream-Verarbeitung. Nicht geeignet für zeilenweise Verarbeitung oder Benutzereingaben.

    – Sean

    15. Oktober 2013 um 11:34 Uhr

  • Ich vermute, dass dies mit der Erkennung von tty in libc zusammenhängt. Wenn Sie also eine Pipe auf einer interaktiven Shell erkennen, wird kein tty erkannt. Unbuffer von Expect-Dev ist ein praktisches Dienstprogramm, von dem ich glaube, dass es ein Shim über ld_preload einfügt, sodass is_atty true zurückgibt (I vermute, dass es so ist)

    – Mâtt Frëëman

    12. März 2015 um 8:16 Uhr


  • @ Sean: falsch. for line in sys.stdin: nicht “blockieren bis EOF”. Da ist ein Read-Ahead-Bug in Python 2 die die Zeilen verzögert, bis der entsprechende Puffer voll ist. Es handelt sich um ein Pufferungsproblem, das nichts mit EOF zu tun hat. Um das Problem zu umgehen, verwenden Sie for line in iter(sys.stdin.readline, ''): (verwenden io.open() für normale Dateien). Sie brauchen es in Python 3 nicht.

    – jfs

    23. Januar 2016 um 7:38 Uhr


1158920cookie-checkWie lese ich von stdin?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy