Question Comment lisez-vous depuis stdin en Python?


J'essaie de faire une partie du code golf défis, mais ils exigent tous l'apport de stdin. Comment puis-je obtenir cela en Python?


1171
2017-09-20 05:48


origine


Réponses:


Vous pouvez utiliser le fileinput module:

import fileinput

for line in fileinput.input():
    pass

fileinput fera une boucle sur toutes les lignes de l'entrée spécifiées en tant que noms de fichiers dans les arguments de la ligne de commande, ou sur l'entrée standard si aucun argument n'est fourni.


801
2017-09-20 05:53



Il y a plusieurs façons de le faire.

  • sys.stdin est un objet de type fichier sur lequel vous pouvez appeler des fonctions read ou readlines si vous voulez tout lire ou si vous voulez tout lire et le diviser par newline automatiquement. (Tu dois import sys pour que cela fonctionne.)

  • Si tu veux rapide l'utilisateur pour la saisie, vous pouvez utiliser raw_input en Python 2.X, et juste input en Python 3.

  • Si vous voulez simplement lire les options de la ligne de commande, vous pouvez y accéder via le sys.argv liste.

Vous trouverez probablement cet article de Wikibook sur les E / S en Python être aussi une référence utile.


584
2017-07-20 10:30



import sys

for line in sys.stdin:
    print line

331
2018-03-03 19:05



Python a également des fonctions intégrées input() et raw_input(). Voir la documentation Python sous Fonctions intégrées.

Par exemple,

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

ou

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

180
2017-09-30 09:08



Voici de Apprendre Python:

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

Sur Unix, vous pouvez le tester en faisant quelque chose comme:

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

Sous Windows ou DOS, vous feriez:

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

160
2017-07-30 04:10



La réponse proposée par d'autres:

for line in sys.stdin:
  print line

est très simple et pythonique, mais il faut noter que le script attendra EOF avant de commencer à itérer sur les lignes d'entrée.

Cela signifie que tail -f error_log | myscript.py ne traitera pas les lignes comme prévu.

Le script correct pour un tel cas d'utilisation serait:

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

    if not line:
        break

    print line

METTRE À JOUR
Des commentaires il a été effacé que sur Python 2 seulement il pourrait y avoir un tampon impliqué, de sorte que vous finissiez par attendre que le tampon remplisse ou EOF avant que l'appel d'impression soit émis.


85
2017-08-09 16:31



Comment lisez-vous depuis stdin en Python?

J'essaie de faire quelques-uns des défis de golf de code, mais ils exigent tous l'entrée à prendre de stdin. Comment puis-je obtenir cela en Python?

Vous pouvez utiliser:

  • sys.stdin - Un objet de type fichier - appel sys.stdin.read() lire tout.
  • input(prompt) - passer une invite facultative à la sortie, il lit de stdin jusqu'à la première ligne, qu'il dépouille. Vous auriez à le faire à plusieurs reprises pour obtenir plus de lignes, à la fin de l'entrée, il soulève EOFError. (Probablement pas génial pour le golf.) Dans Python 2, c'est rawinput(prompt).
  • open(0).read() - En Python 3 open accepte Descripteurs de fichiers (entiers représentant les ressources d'E / S du système d'exploitation), et 0 est le descripteur de stdin. Il renvoie un objet semblable à un fichier sys.stdin - Probablement votre meilleur pari pour le golf.
  • open('/dev/stdin').read() - semblable à open(0), fonctionne sur Python 2 et 3, mais pas sur Windows (ou même Cygwin).
  • fileinput.input() - retourne un itérateur sur les lignes de tous les fichiers listés dans sys.argv[1:], ou stdin si pas donné. Utilisez comme ''.join(fileinput.input()).

Tous les deux sys et fileinput doivent être importés, respectivement, bien sûr.

Rapide sys.stdin exemples compatibles avec Python 2 et 3, Windows, Unix

Vous avez juste besoin de read de sys.stdinPar exemple, si vous redirigez les données vers stdin:

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

exemple de fichier

Dis que tu as un fichier, inputs.txt, nous pouvons accepter ce fichier et l'écrire:

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

Réponse plus longue

Voici une démo complète, facilement reproductible, utilisant deux méthodes, la fonction intégrée, input (utilisation raw_input en Python 2), et sys.stdin. Les données ne sont pas modifiées, donc le traitement est une non-opération.

Pour commencer, créons un fichier pour les entrées:

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

Et en utilisant le code que nous avons déjà vu, nous pouvons vérifier que nous avons créé le fichier:

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

Voici l'aide sur sys.stdin.read de 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.

Fonction intégrée, input (raw_input en Python 2)

La fonction intégrée input lit à partir de l'entrée standard jusqu'à une nouvelle ligne, qui est supprimée print, qui ajoute une nouvelle ligne par défaut.) Cela se produit jusqu'à ce qu'il obtienne EOF (End Of File), à ​​quel point il soulève EOFError.

Ainsi, voici comment vous pouvez utiliser input en Python 3 (ou raw_input en Python 2) à lire depuis stdin - donc nous créons un module Python que nous appelons stdindemo.py:

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

Et imprimons-le pour nous assurer que c'est comme nous l'espérons:

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

Encore, input lit jusqu'à la nouvelle ligne et l'enlève essentiellement de la ligne. print ajoute une nouvelle ligne. Ainsi, pendant qu'ils modifient l'entrée, leurs modifications s'annulent. (Donc, ils sont essentiellement le complément de l'autre.)

Et quand input obtient le caractère de fin de fichier, il soulève EOFError, que nous ignorons, puis quitte le programme.

Et sur Linux / Unix, on peut passer du chat:

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

Ou nous pouvons simplement rediriger le fichier à partir de stdin:

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

Nous pouvons également exécuter le module en tant que script:

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

Voici l'aide sur le builtin input de 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

Ici, nous faisons un script de démonstration en utilisant sys.stdin. Le moyen efficace d'itérer sur un objet semblable à un fichier consiste à utiliser l'objet semblable à un fichier en tant qu'itérateur. La méthode complémentaire pour écrire sur stdout à partir de cette entrée est d'utiliser simplement sys.stdout.write:

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

Imprimez-le pour vous assurer qu'il a l'air correct:

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

Et rediriger les entrées dans le fichier:

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

Golfé dans une commande:

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

Descripteurs de fichier pour le golf

Depuis les descripteurs de fichiers pour stdin et stdout sont 0 et 1 respectivement, nous pouvons également passer ceux à open en Python 3 (pas 2, et notez que nous avons toujours besoin du 'w' pour écrire sur stdout).

Si cela fonctionne sur votre système, il va raser plus de caractères.

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

Python 2 io.open fait cela aussi, mais l'importation prend beaucoup plus de place:

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

Adresser d'autres commentaires et réponses

Un commentaire suggère ''.join(sys.stdin) mais c'est en fait plus long que sys.stdin.read () - plus Python doit créer une liste supplémentaire en mémoire (c'est comme ça str.join fonctionne quand on ne lui donne pas une liste) - pour le contraste:

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

La meilleure réponse suggère:

import fileinput

for line in fileinput.input():
    pass

Mais depuis sys.stdin implémente l'API de fichier, y compris le protocole d'itérateur, qui est exactement le même que celui-ci:

import sys

for line in sys.stdin:
    pass

Une autre réponse Est-ce que suggérer ceci. Rappelez-vous juste que si vous le faites dans un interprète, vous devrez faire Ctrl- si vous êtes sur Linux ou Mac, ou Ctrl-z sur Windows (après Entrer) pour envoyer le caractère de fin de fichier au processus. En outre, cette réponse suggère print(line) - qui ajoute un '\n' jusqu'à la fin - utilisation print(line, end='') à la place (si dans Python 2, vous aurez besoin from __future__ import print_function).

Le vrai cas d'utilisation pour fileinput est pour lire dans une série de fichiers.


49
2017-07-29 15:04



Cela fera écho à l'entrée standard à la sortie standard:

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

36
2018-01-25 10:26



Construire sur toutes les awers en utilisant sys.stdin, vous pouvez aussi faire quelque chose comme ce qui suit pour lire un fichier d'argument si au moins un argument existe, et revenir à stdin sinon:

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

et l'utiliser comme

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

ou

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

ou même

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

Cela ferait que votre script Python se comporte comme de nombreux programmes GNU / Unix tels que cat, grep et sed.


28
2017-08-27 15:43



La puce de code suivante vous aidera (elle lira tout le blocage de stdin à EOF, en une seule chaîne):

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

12
2017-07-20 21:33