私はいくつかのコード ゴルフチャレンジを実行しようとしていますが、すべて から入力を取得する必要がありますstdin
。Pythonでそれを取得するにはどうすればよいですか?
23 に答える
モジュールを使用できfileinput
ます:
import fileinput
for line in fileinput.input():
pass
fileinput
コマンドライン引数で指定されたファイル名として指定された入力のすべての行、または引数が指定されていない場合は標準入力のすべての行をループします。
注:line
末尾に改行が含まれます。それを削除するにはline.rstrip()
いくつかの方法があります。
sys.stdin
関数を呼び出すことができるファイルのようなオブジェクトです。read
またはreadlines
、すべてを読みたい場合、またはすべてを読み込んで改行で自動的に分割したい場合。(これが機能するために必要ですimport sys
。)ユーザーに入力を求める場合は、Python 2.X で使用でき、 Python
raw_input
3 でのみinput
使用できます。実際にコマンド ライン オプションを読みたいだけの場合は、sys.argvリストからアクセスできます。
Python での I/O に関するこの Wikibook の記事も参考になるでしょう。
import sys
for line in sys.stdin:
print(line)
これには、最後に改行文字が含まれることに注意してください。最後に改行を削除するには、line.rstrip()
@brittohalloran が言ったように使用します。
Python には組み込み関数input()
とraw_input()
. 組み込み関数の下の Python ドキュメントを参照してください。
例えば、
name = raw_input("Enter your name: ") # Python 2.x
また
name = input("Enter your name: ") # Python 3
これはLearning Pythonからのものです:
import sys
data = sys.stdin.readlines()
print "Counted", len(data), "lines."
Unix では、次のようにしてテストできます。
% cat countlines.py | python countlines.py
Counted 3 lines.
Windows または DOS では、次のようにします。
C:\> type countlines.py | python countlines.py
Counted 3 lines.
Python で stdin からどのように読み取りますか?
私はいくつかのコード ゴルフ チャレンジを実行しようとしていますが、すべて標準入力から入力を取得する必要があります。Pythonでそれを取得するにはどうすればよいですか?
以下を使用できます。
sys.stdin
- ファイルのようなオブジェクト -sys.stdin.read()
すべてを読み取るための呼び出し。input(prompt)
- 出力するオプションのプロンプトを渡します。標準入力から最初の改行まで読み取り、それを削除します。より多くの行を取得するには、これを繰り返し実行する必要があります。入力の最後で EOFError が発生します。(おそらくゴルフには向いていません。) Python 2 では、これはrawinput(prompt)
.open(0).read()
- Python 3 では、組み込み関数はファイル記述子(オペレーティング システムの IO リソースを表す整数)open
を受け入れ、0 は の記述子です。これは次のようなファイルのようなオブジェクトを返します- おそらくゴルフに最適です。Python 2 では、これは.stdin
sys.stdin
io.open
open('/dev/stdin').read()
- と同様にopen(0)
、Python 2 および 3 で動作しますが、Windows (または Cygwin でさえ) では動作しません。fileinput.input()
- にリストされているすべてのファイルの行に対する反復子を返します。指定されsys.argv[1:]
ていない場合は stdin を返します。のように使用し''.join(fileinput.input())
ます。
もちろん、 と の両方sys
をfileinput
それぞれインポートする必要があります。
sys.stdin
Python 2 および 3、Windows、Unix と互換性のある簡単な例
たとえば、データを stdin にパイプする場合は、read
fromを実行する必要があります。sys.stdin
$ echo foo | python -c "import sys; print(sys.stdin.read())"
foo
sys.stdin
デフォルトのテキスト モードになっていることがわかります。
>>> import sys
>>> sys.stdin
<_io.TextIOWrapper name='<stdin>' mode='r' encoding='UTF-8'>
ファイルの例
ファイル があるとします。inputs.txt
そのファイルを受け入れて書き戻すことができます。
python -c "import sys; sys.stdout.write(sys.stdin.read())" < inputs.txt
より長い答え
これは、組み込み関数input
( raw_input
Python 2 で使用) との 2 つのメソッドを使用した、完全で簡単に複製可能なデモsys.stdin
です。データは変更されていないため、処理は非操作です。
まず、入力用のファイルを作成しましょう。
$ python -c "print('foo\nbar\nbaz')" > inputs.txt
そして、既に見たコードを使用して、ファイルが作成されたことを確認できます。
$ python -c "import sys; sys.stdout.write(sys.stdin.read())" < inputs.txt
foo
bar
baz
sys.stdin.read
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.
組み込み関数input
( raw_input
Python 2 の場合)
組み込み関数input
は、標準入力から改行まで読み取ります。改行は削除されます (補完print
し、デフォルトで改行が追加されます)。これは、EOF (End Of File) を取得するまで発生し、その時点で が発生しEOFError
ます。
したがって、input
Python 3 (またはraw_input
Python 2) で stdin から読み取る方法は次のとおりです。したがって、stdidemo.py と呼ばれる Python モジュールを作成します。
$ python -c "print('try:\n while True:\n print(input())\nexcept EOFError:\n pass')" > stdindemo.py
そして、それを印刷して、期待どおりであることを確認しましょう。
$ python -c "import sys; sys.stdout.write(sys.stdin.read())" < stdindemo.py
try:
while True:
print(input())
except EOFError:
pass
繰り返しinput
ますが、改行まで読み取り、基本的に行から削除します。print
改行を追加します。したがって、両方が入力を変更している間、変更はキャンセルされます。(したがって、それらは本質的に互いの補完物です。)
そして、input
ファイル終了文字を取得すると、EOFError が発生しますが、これは無視してプログラムを終了します。
Linux/Unix では、cat からパイプできます:
$ cat inputs.txt | python -m stdindemo
foo
bar
baz
または、stdin からファイルをリダイレクトすることもできます。
$ python -m stdindemo < inputs.txt
foo
bar
baz
モジュールをスクリプトとして実行することもできます。
$ python stdindemo.py < inputs.txt
foo
bar
baz
input
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
ここでは、 を使用してデモ スクリプトを作成しsys.stdin
ます。ファイルのようなオブジェクトを反復処理する効率的な方法は、ファイルのようなオブジェクトを反復子として使用することです。この入力から stdout に書き込む補完的な方法は、単純に次を使用することsys.stdout.write
です。
$ python -c "print('import sys\nfor line in sys.stdin:\n sys.stdout.write(line)')" > stdindemo2.py
印刷して、正しく表示されることを確認します。
$ python -c "import sys; sys.stdout.write(sys.stdin.read())" < stdindemo2.py
import sys
for line in sys.stdin:
sys.stdout.write(line)
入力をファイルにリダイレクトします。
$ python -m stdindemo2 < inputs.txt
foo
bar
baz
コマンドにゴルフ:
$ python -c "import sys; sys.stdout.write(sys.stdin.read())" < inputs.txt
foo
bar
baz
Golfing のファイル記述子
stdin
とのファイル記述子はstdout
それぞれ 0 と 1 であるため、これらをopen
Python 3 に渡すこともできます (2 ではありません。stdout に書き込むには 'w' がまだ必要であることに注意してください)。
これがシステムで機能する場合、より多くの文字が削除されます。
$ python -c "open(1,'w').write(open(0).read())" < inputs.txt
baz
bar
foo
Python 2io.open
もこれを行いますが、インポートにはさらに多くのスペースが必要です。
$ python -c "from io import open; open(1,'w').write(open(0).read())" < inputs.txt
foo
bar
baz
他のコメントと回答への対処
1 つのコメントは''.join(sys.stdin)
ゴルフを示唆していますが、実際には sys.stdin.read() よりも長くなります。さらに、Python はメモリ内に追加のリストを作成する必要があります (リストがstr.join
指定されていない場合は、このように機能します)。対照的に:
''.join(sys.stdin)
sys.stdin.read()
一番の答えは次のことを示唆しています:
import fileinput
for line in fileinput.input():
pass
しかし、sys.stdin
イテレータ プロトコルを含むファイル API を実装しているため、これは次のようになります。
import sys
for line in sys.stdin:
pass
別の答えはこれを示唆しています。インタープリターでこれを行う場合は、Linux または Mac を使用している場合、またはWindows を使用している場合(Ctrlの後)、ファイルの終わり文字をプロセスに送信する必要があることを覚えておいてください。また、その答えは、最後に a を追加することを示唆しています-代わりに使用します(Python 2の場合は、が必要です)。dCtrlzEnterprint(line)
'\n'
print(line, end='')
from __future__ import print_function
の実際の使用例fileinput
は、一連のファイルを読み取ることです。
他の人が提案した答え:
for line in sys.stdin:
print line
は非常に単純でpythonicですが、スクリプトはEOFまで待機してから、入力行の反復を開始することに注意する必要があります。
これは、tail -f error_log | myscript.py
ラインが期待どおりに処理されないことを意味します。
このようなユースケースの正しいスクリプトは次のとおりです。
while 1:
try:
line = sys.stdin.readline()
except KeyboardInterrupt:
break
if not line:
break
print line
更新
コメントから、Python 2ではバッファリングのみが関係している可能性があることが明らかになりました。そのため、印刷呼び出しが発行される前に、バッファがいっぱいになるかEOFを待つことになります。
これにより、標準入力が標準出力にエコーされます。
import sys
line = sys.stdin.readline()
while line:
print line,
line = sys.stdin.readline()
を使用してすべての回答に基づいて構築するsys.stdin
と、次のようなことを行って、少なくとも 1 つの引数が存在する場合は引数ファイルから読み取り、それ以外の場合は stdin にフォールバックすることもできます。
import sys
f = open(sys.argv[1]) if len(sys.argv) > 1 else sys.stdin
for line in f:
# Do your stuff
どちらかとして使用します
$ python do-my-stuff.py infile.txt
また
$ cat infile.txt | python do-my-stuff.py
あるいは
$ python do-my-stuff.py < infile.txt
cat
これにより、Python スクリプトは、grep
やなどの多くの GNU/Unix プログラムのように動作しsed
ます。
これまで誰もこのハッキングについて言及していなかったことに、私はかなり驚いています。
python -c "import sys; set(map(sys.stdout.write,sys.stdin))"
python2では、set()
呼び出しをドロップできますが、どちらの方法でも使用できます
これを試して:
import sys
print sys.stdin.read().upper()
そしてそれをチェックしてください:
$ echo "Hello World" | python myFile.py
次のように、標準入力から読み取り、入力を「データ」に格納できます。
data = ""
for line in sys.stdin:
data += line
から読み取りますが、Windows でバイナリ データを読み取るにはsys.stdin
、特に注意する必要があります。sys.stdin
\r\n
\n
解決策は、Windows + Python 2 が検出された場合はモードをバイナリに設定し、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 3の場合は次のようになります。
# Filename e.g. cat.py
import sys
for line in sys.stdin:
print(line, end="")
各行の後に改行を追加しないため、これは基本的に cat(1) の単純な形式です。これを使用できます(次のchmod +x cat.py
ような方法でファイルを実行可能としてマークした後:
echo Hello | ./cat.py
パイプされたソケットを介して読み取るためにこれを機能させるときに、いくつかの問題がありました。ソケットが閉じられると、アクティブなループで空の文字列が返され始めました。これが私の解決策です(Linuxでのみテストしましたが、他のすべてのシステムで機能することを願っています)
import sys, os
sep=os.linesep
while sep == os.linesep:
data = sys.stdin.readline()
sep = data[-len(os.linesep):]
print '> "%s"' % data.strip()
したがって、ソケットでリッスンを開始すると、正しく機能します (たとえば、bash で):
while :; do nc -l 12345 | python test.py ; done
また、telnet で呼び出すか、ブラウザで localhost:12345 にアクセスするだけです。