(10月23日、19:48に回答)
私はそれほど大きなPythonerではありませんが、この構文を一度見つけたのですが、どこから来たかを忘れてしまったので、ドキュメントに書こうと思いました。
のsys.stdout.write
代わりに使用する場合print
(違いは、sys.stdout.write
引数を関数としてかっこで囲みます- print
しないでください)、ワンライナーの場合、コマンドとの順序を逆for
にしてセミコロンを削除することで回避できます、コマンドを角括弧で囲みます。つまり、
python -c "import sys; [sys.stdout.write('rob\n') for r in range(10)]"
この構文がPythonでどのように呼び出されるかわかりません:)
お役に立てれば、
乾杯!
(2013年4月9日20:57:30編集EDIT)さて、私はようやく、これらのワンライナーの角かっこが何であるかを見つけたと思います。それらは「リスト内包表記」(どうやら)です。最初に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のヒントとコツ–初版-Pythonチュートリアル| Dream.In.Code:
覚えていると思いますが、単一行ジェネレーターの標準形式は、括弧内の一種の1行の「for」ループです。これにより、「一発」の反復可能なオブジェクトが生成されます。このオブジェクトは、一方向にのみ反復でき、最後に到達すると再利用できません。
「リスト内包表記」は、通常の大括弧-()-が大括弧-[]に置き換えられていることを除いて、通常の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。データ構造に記載されています。リスト内包表記—「リスト内包表記はリストを作成する簡潔な方法を提供する」としてのPython v2.7.4のドキュメント。おそらく、ここでリストの制限された「実行可能性」がワンライナーで機能します。
まあ、私がここであまりにもマークを外れていないことを願っています...
EDIT2:ネストされていないforループが2つある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]
b
forループが明示的に2回実行されたため、2番目の「リスト」には2つの要素があることに注意してください。ただし、sys.stdout.write()
どちらの場合も結果は(どうやら)None
でした。