Ich versuche, einige der Code-Golf- Herausforderungen zu meistern, aber für alle muss der Input entnommen werden stdin
. Wie bekomme ich das in Python?
1470
Ich versuche, einige der Code-Golf- Herausforderungen zu meistern, aber für alle muss der Input entnommen werden stdin
. Wie bekomme ich das in Python?
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 Dateinamen in Befehlszeilenargumenten angegeben sind, oder die Standardeingabe, wenn keine Argumente angegeben sind.
Hinweis: line
Enthält einen nachgestellten Zeilenumbruch. um es zu entfernen verwendenline.rstrip()
Es gibt einige Möglichkeiten, dies zu tun.
sys.stdin
ist ein dateiähnliches Objekt, für das Sie Funktionen aufrufen könnenread
oderreadlines
wenn Sie alles lesen oder alles lesen und automatisch durch Zeilenumbruch teilen möchten. (Sie müssen,import sys
damit dies funktioniert.)Wenn Sie möchten , aufgefordert , den Benutzer zur Eingabe, können Sie
raw_input
in Python 2.x, und nurinput
in Python 3.Wenn Sie eigentlich nur Befehlszeilenoptionen lesen möchten, können Sie über die Liste sys.argv darauf zugreifen .
Sie werden diesen Wikibook-Artikel über E / A in Python wahrscheinlich auch als nützliche Referenz finden.
quelle
Beachten Sie, dass dies am Ende ein Zeilenumbruchzeichen enthält. Um die neue Zeile am Ende zu entfernen, verwenden Sie
line.rstrip()
wie @brittohalloran sagte.quelle
\r\n
Zeilenenden umgehenPython hat auch eingebaute Funktionen
input()
undraw_input()
. Weitere Informationen finden Sie in der Python-Dokumentation unter Integrierte Funktionen .Zum Beispiel,
oder
quelle
Hier ist aus Python lernen :
Unter Unix können Sie es testen, indem Sie Folgendes tun:
Unter Windows oder DOS würden Sie Folgendes tun:
quelle
print(sum(chunk.count('\n') for chunk in iter(partial(sys.stdin.read, 1 << 15), '')))
. siehewc-l.py
cat
hier ist überflüssig. Der korrekte Aufruf für Unix-Systeme lautetpython countlines.py < countlines.py
.readlines()
. Dateiobjekte sollen wiederholt werden, ohne dass alle Daten im Speicher materialisiert werden.Sie können verwenden:
sys.stdin
- Ein dateiähnliches Objekt - Aufrufsys.stdin.read()
, um alles zu lesen.input(prompt)
- Übergeben Sie eine optionale Eingabeaufforderung, sie liest von stdin bis zur ersten neuen Zeile, die sie 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 diesrawinput(prompt)
.open(0).read()
- In Python 3open
akzeptiert die integrierte Funktion Dateideskriptoren (Ganzzahlen , die die E / A- Ressourcen des Betriebssystems darstellen), und 0 ist der Deskriptor vonstdin
. Es gibt ein dateiähnliches Objekt zurücksys.stdin
- wahrscheinlich die beste Wahl zum Golfen. In Python 2 ist diesio.open
.open('/dev/stdin').read()
-open(0)
funktioniert ähnlich unter Python 2 und 3, jedoch nicht unter Windows (oder sogar Cygwin).fileinput.input()
- gibt einen Iterator über Zeilen in allen in aufgelisteten Dateien zurücksys.argv[1:]
oder stdin, falls nicht angegeben. Verwenden Sie wie''.join(fileinput.input())
.Beide
sys
undfileinput
müssen natürlich jeweils importiert werden.Kurze
sys.stdin
Beispiele, die mit Python 2 und 3, Windows und Unix kompatibel sindSie müssen nur
read
aussys.stdin
, zum Beispiel, wenn Sie Rohrdaten stdin:Wir können sehen, dass
sys.stdin
sich dies im Standardtextmodus befindet:Dateibeispiel
Angenommen, Sie haben eine Datei.
inputs.txt
Wir können diese Datei akzeptieren und wieder ausschreiben:Längere Antwort
Hier ist eine vollständige, leicht replizierbare Demo mit zwei Methoden, der integrierten Funktion
input
(Verwendungraw_input
in Python 2) undsys.stdin
. Die Daten sind unverändert, sodass die Verarbeitung nicht ausgeführt wird.Lassen Sie uns zunächst eine Datei für Eingaben erstellen:
Mit dem Code, den wir bereits gesehen haben, können wir überprüfen, ob wir die Datei erstellt haben:
Hier ist die Hilfe
sys.stdin.read
von Python 3:Eingebaute Funktion
input
(raw_input
in Python 2)Die eingebaute Funktion
input
liest von der Standardeingabe bis zu einer neuen Zeile, die entfernt wird (ergänzendprint
, wodurch standardmäßig eine neue Zeile hinzugefügt wird). Dies geschieht, bis EOF (End Of File) abgerufen wird und an diesem Punkt ausgelöst wirdEOFError
.So können Sie
input
in Python 3 (oderraw_input
in Python 2) aus stdin lesen - also erstellen wir ein Python-Modul, das wir stdindemo.py nennen:Und drucken wir es wieder aus, um sicherzustellen, dass es so ist, wie wir es erwarten:
Auch hier
input
liest , bis die Newline und im Wesentlichen Streifen es von der Linie.print
fügt eine neue Zeile hinzu. Während beide die Eingabe ändern, werden ihre Änderungen abgebrochen. (Sie ergänzen sich also im Wesentlichen gegenseitig.)Und wenn
input
das Zeichen für das Dateiende angezeigt wird, wird EOFError ausgelöst, das wir ignorieren und dann aus dem Programm beenden.Und unter Linux / Unix können wir von cat leiten:
Oder wir können die Datei einfach von stdin umleiten:
Wir können das Modul auch als Skript ausführen:
Hier ist die Hilfe zum eingebauten
input
Python 3:sys.stdin
Hier machen wir ein Demo-Skript mit
sys.stdin
. Der effiziente Weg, um über ein dateiähnliches Objekt zu iterieren, besteht darin, das dateiähnliche Objekt als Iterator zu verwenden. Die ergänzende Methode zum Schreiben von dieser Eingabe in stdout besteht darin, einfach Folgendes zu verwendensys.stdout.write
:Drucken Sie es wieder aus, um sicherzustellen, dass es richtig aussieht:
Und die Eingaben in die Datei umleiten:
Golf in einen Befehl:
Dateideskriptoren für das Golfen
Da die Dateideskriptoren für
stdin
undstdout
0 bzw. 1 sind, können wir diese auchopen
in Python 3 übergeben (nicht 2, und beachten Sie, dass wir zum Schreiben in stdout immer noch das 'w' benötigen).Wenn dies auf Ihrem System funktioniert, werden mehr Zeichen entfernt.
Python 2
io.open
macht das auch, aber der Import nimmt viel mehr Platz in Anspruch:Adressierung anderer Kommentare und Antworten
Ein Kommentar schlägt
''.join(sys.stdin)
für das Golfen vor, aber das ist tatsächlich länger als sys.stdin.read () - plus Python muss eine zusätzliche Liste im Speicher erstellen (sostr.join
funktioniert es, wenn keine Liste angegeben wird) - für den Kontrast:Die beste Antwort lautet:
Da
sys.stdin
jedoch die Datei-API einschließlich des Iterator-Protokolls implementiert wird, ist dies genau das Gleiche wie folgt:Eine andere Antwort legt dies nahe. Denken Sie daran , dass , wenn Sie es in einem Dolmetscher zu tun, werden Sie tun müssen Ctrl- dwenn Sie unter Linux oder Mac, oder Ctrl- zunter Windows (nach Enter) , um die End-of-Datei Zeichen an den Prozess zu senden. Diese Antwort schlägt außerdem vor, stattdessen
print(line)
eine'\n'
Verwendung zuprint(line, end='')
verwenden (falls in Python 2 erforderlichfrom __future__ import print_function
).Der eigentliche Anwendungsfall für
fileinput
ist das Einlesen einer Reihe von Dateien.quelle
Die von anderen vorgeschlagene Antwort:
ist sehr einfach und pythonisch, aber es muss beachtet werden, dass das Skript bis EOF wartet, bevor es mit der Iteration in den Eingabezeilen beginnt.
Dies bedeutet, dass
tail -f error_log | myscript.py
Zeilen nicht wie erwartet verarbeitet werden.Das richtige Skript für einen solchen Anwendungsfall wäre:
UPDATE
Aus den Kommentaren geht hervor, dass unter Python 2 möglicherweise nur Pufferung erforderlich ist, sodass Sie am Ende darauf warten müssen, dass der Puffer oder EOF gefüllt wird, bevor der Druckaufruf ausgegeben wird.
quelle
for line in sys.stdin:
Muster wartet nicht auf EOF. Wenn Sie jedoch sehr kleine Dateien testen, werden die Antworten möglicherweise gepuffert. Testen Sie mit mehr Daten, um festzustellen, ob Zwischenergebnisse gelesen werden.print line
ist in 3.1.3 nicht aufgewacht,print(line)
tut es aber .for line in sys.stdin:
blockiert nicht bis EOF. In Python 2 gibt es einen Read-Ahead-Fehler , der die Zeilen verzögert, bis der entsprechende Puffer voll ist. Es handelt sich um ein Pufferproblem, das nicht mit EOF zusammenhängt.for line in iter(sys.stdin.readline, ''):
Verwenden Sieio.open()
zur Umgehung dieses Problems ( für normale Dateien verwenden). Sie brauchen es nicht in Python 3.Dies gibt die Standardeingabe an die Standardausgabe weiter:
quelle
Aufbauend auf allen Antworten
sys.stdin
, die Sie verwenden , können Sie auch Folgendes tun, um aus einer Argumentdatei zu lesen, wenn mindestens ein Argument vorhanden ist, und ansonsten auf stdin zurückgreifen:und benutze es entweder
oder
oder auch
Das wäre Ihr Python - Skript verhalten sich wie viele GNU / Unix - Programme machen wie
cat
,grep
undsed
.quelle
argparse
ist eine einfache LösungBeispiel, das mit beiden Python-Versionen 2 und 3 kompatibel ist:
Sie können dieses Skript auf verschiedene Arten ausführen:
1. Verwenden von
stdin
oder kürzer durch Ersetzen
echo
durch hier Zeichenfolge :2. Verwenden eines Dateinamenarguments
3. Verwenden Sie
stdin
den speziellen Dateinamen-
quelle
add_argument('--in'
und dann zum Skript weiterleiten und--in -
zur Befehlszeile hinzufügen . PSin
ist kein sehr guter Name für eine Variable / ein Attribut.in
ist nicht nur ein schlechter Name für eine Variable, sondern auch illegal.args.in.read()
löst aufgrund desin
reservierten Schlüsselworts einen InvalidSyntax-Fehler aus . Kann einfach umbenannt werden, uminfile
die Python Argparse-Dokumente zu mögen: docs.python.org/3/library/…Der folgende Code-Chip hilft Ihnen dabei (er liest alle stdin-Blockierungen
EOF
in einer Zeichenfolge):quelle
Ich bin ziemlich erstaunt, dass bisher niemand diesen Hack erwähnt hat:
In Python2 können Sie den
set()
Anruf abbrechen , aber es würde so oder so lautenquelle
readlines
diese Aufteilung in Zeilen und dannjoin
wieder verwenden? Sie können einfach schreibenprint(sys.stdin.read())
write
kehrt zurückNone
und die festgelegte Größe würde niemals größer als 1 (=len(set([None]))
) seinVersuche dies:
und überprüfen Sie es mit:
quelle
Sie können wie folgt aus stdin lesen und Eingaben in "Daten" speichern :
quelle
data = sys.stdin.read()
ohne das Problem wiederholter Verkettungen von Zeichenfolgen durchgeführt werden.Lesen von
sys.stdin
, aber um Binärdaten unter Windows zu lesen , müssen Sie besonders vorsichtig sein, da diesesys.stdin
im Textmodus geöffnet sind und das\r\n
Ersetzen durch sie beschädigt\n
.Die Lösung besteht darin, den Modus auf binär zu setzen, wenn Windows + Python 2 erkannt wird, und unter Python 3 zu verwenden
sys.stdin.buffer
.quelle
Ich benutze die folgende Methode, sie gibt einen String von stdin zurück (ich benutze ihn für das JSON-Parsing). Es funktioniert mit Pipe und Eingabeaufforderung unter Windows (noch nicht unter Linux getestet). Bei der Eingabeaufforderung zeigen zwei Zeilenumbrüche das Ende der Eingabe an.
quelle
Das Problem habe ich mit der Lösung
Wenn Sie keine Daten an stdin übergeben, werden diese für immer blockiert. Deshalb liebe ich diese Antwort : Überprüfen Sie zuerst, ob Daten zu stdin vorhanden sind, und lesen Sie sie dann. Das habe ich letztendlich getan:
quelle
select
Aufruf fast nie "bereit" ist. oder Sie könnten auch Probleme haben, wenn stdin mit einer Datei auf einem langsamen Medium (Netzwerk, CD, Band usw.) verbunden ist. Sie sagten: "Wenn Sie keine Daten an stdin übergeben, werden diese für immer blockiert." ist ein Problem , aber ich würde sagen, es ist eine Funktion . Die meisten CLI-Programme (z. B.cat
) funktionieren auf diese Weise, und dies wird erwartet. EOF ist das einzige, worauf Sie sich verlassen sollten, um das Ende der Eingabe zu erkennen.Ich hatte einige Probleme, als dies zum Lesen über die daran angeschlossenen Steckdosen funktionierte. Als der Socket geschlossen wurde, gab er eine leere Zeichenfolge in einer aktiven Schleife zurück. Das ist also meine Lösung dafür (die ich nur unter Linux getestet habe, aber ich hoffe, dass sie auf allen anderen Systemen funktioniert).
Wenn Sie also anfangen, einen Socket zu hören, funktioniert er ordnungsgemäß (z. B. in Bash):
Und Sie können es mit Telnet aufrufen oder einfach einen Browser auf localhost zeigen: 12345
quelle
Was das betrifft:
for line in sys.stdin:
Ich habe es gerade unter Python 2.7 (auf Vorschlag eines anderen) für eine sehr große Datei versucht, und ich empfehle es nicht, genau aus den oben genannten Gründen (lange passiert nichts).
Am Ende hatte ich eine etwas pythonischere Lösung (und sie funktioniert bei größeren Dateien):
Dann kann ich das Skript lokal ausführen als:
quelle
sys.stdin
das Skript als Befehlszeilenargument.sys.stdin
als Befehlszeilenargument an das Skript übergeben? Argumente sind Zeichenfolgen und Streams sind dateiähnliche Objekte, sie sind nicht gleich.sys.stdin
handelt es sich um ein dateiähnliches ObjektFür Python 3 wäre das:
Dies ist im Grunde eine einfache Form von Katze (1), da nicht nach jeder Zeile eine neue Zeile hinzugefügt wird. Sie können dies verwenden (nachdem Sie die ausführbare Datei
chmod +x cat.py
wie folgt markiert haben :quelle
Dort
os.read(0, x)
liest xbytes von 0, was stdin darstellt. Dies ist ein ungepufferter Lesevorgang, niedriger als sys.stdin.read ()quelle
Wenn Sie den
-c
Befehl auf knifflige Weise verwenden, können Sie anstelle desstdin
(und in einigen Fällen flexibleren) Befehls auch einen Shell-Skriptbefehl an Ihren Python-Befehl übergeben, indem Sie den Befehl sell in Anführungszeichen in einer durch ein$
Zeichen gestellten Klammer setzen .z.B
Dies zählt die Anzahl der Zeilen aus der Verlaufsdatei von goldendict.
quelle