(10 年 11 月 23 日
19:48 に回答済み) 私はあまり Python が得意ではありませんが、この構文を一度見つけて、どこから来たのか忘れてしまったので、文書化しようと思いました:
sys.stdout.write
代わりにprint
(の違いは、sys.stdout.write
括弧内に引数を関数として受け取りますが、そうではありprint
ません) の代わりに使用すると、ワンライナーの場合、コマンドと の順序を逆にしてfor
、セミコロンを削除することで回避できます。コマンドを角括弧で囲みます。つまり、次のようになります。
python -c "import sys; [sys.stdout.write('rob\n') for r in range(10)]"
この構文がPythonでどのように呼び出されるかわかりません:)
お役に立てれば、
乾杯!
(EDIT Tue Apr 9 20:57:30 2013)さて、私は最終的にこれらのワンライナーの角括弧が何であるかを見つけたと思います。それらは「リスト内包表記」です(明らかに)。最初に Python 2.7 でこれに注意してください:
$ STR=abc
$ echo $STR | python -c "import sys,re; a=(sys.stdout.write(line) for line in sys.stdin); print a"
<generator object <genexpr> at 0xb771461c>
したがって、丸括弧/括弧内のコマンドは「ジェネレータ オブジェクト」と見なされます。呼び出して「反復」next()
すると、括弧内のコマンドが実行されます(出力の「abc」に注意してください):
$ echo $STR | python -c "import sys,re; a=(sys.stdout.write(line) for line in sys.stdin); a.next() ; print a"
abc
<generator object <genexpr> at 0xb777b734>
ここで角括弧を使用すると、コマンドを実行するために呼び出す必要がないことに注意してくださいnext()
。割り当て後すぐに実行されます。ただし、後で調べると、次のことa
がわかりNone
ます。
$ echo $STR | python -c "import sys,re; a=[sys.stdout.write(line) for line in sys.stdin]; print a"
abc
[None]
角括弧の場合、これは探すべき多くの情報を残しません-しかし、私はこのページに出くわしました。
Python のヒントとコツ - 第 1 版 - Python チュートリアル | Dream.In.Code :
思い出すと、単一行ジェネレーターの標準形式は、括弧内の 1 行の「for」ループのようなものです。これにより、「ワンショット」の反復可能なオブジェクトが生成されます。これは、一方向にのみ反復でき、最後に到達すると再利用できないオブジェクトです。
「リスト内包表記」は、通常の角括弧 ( ) が角括弧 [ ] に置き換えられていることを除いて、通常の 1 行ジェネレーターとほとんど同じように見えます。連想リスト内包表記の主な利点は、「1 回限りの」反復可能なオブジェクトではなく「リスト」を生成することです。これにより、前後に移動したり、要素を追加したり、並べ替えたりすることができます。
実際、それはリストです-実行されるとすぐに最初の要素が none になるだけです:
$ echo $STR | python -c "import sys,re; print [sys.stdout.write(line) for line in sys.stdin].__class__"
abc
<type 'list'>
$ echo $STR | python -c "import sys,re; print [sys.stdout.write(line) for line in sys.stdin][0]"
abc
None
リスト内包表記については、5. データ構造: 5.1.4 に記載されています。リスト内包表記 — Python v2.7.4 のドキュメント「リスト内包表記は、リストを作成するための簡潔な方法を提供します」; おそらく、リストの制限された「実行可能性」がワンライナーで機能するのはここです。
まあ、私がここであまりにも的外れでないことを願っています...
EDIT2: これは、ネストされていない 2 つの for ループを含む 1 行のコマンド ラインです。両方とも「リスト内包表記」角括弧で囲まれています。
$ echo $STR | python -c "import sys,re; a=[sys.stdout.write(line) for line in sys.stdin]; b=[sys.stdout.write(str(x)) for x in range(2)] ; print a ; print b"
abc
01[None]
[None, None]
2 番目の「リスト」b
には、for ループが明示的に 2 回実行されたため、2 つの要素が含まれていることに注意してください。ただし、sys.stdout.write()
両方の場合の結果は (どうやら)None
でした。