(antwortete am 23. November 10 um 19:48
Uhr ) Ich bin nicht wirklich ein großer Pythoner - aber ich habe diese Syntax einmal gefunden und vergessen, woher sie stammt, also dachte ich, ich würde sie dokumentieren:
Wenn Sie sys.stdout.write
anstelle von print
( der Unterschied besteht darin, dass sys.stdout.write
Argumente als Funktion in Klammern verwendet werden - wohingegen print
dies nicht der Fall ist ), können Sie bei einem Einzeiler die Reihenfolge des Befehls umkehren und for
das Semikolon entfernen. und Einschließen des Befehls in eckige Klammern, dh:
python -c "import sys; [sys.stdout.write('rob\n') for r in range(10)]"
Habe keine Ahnung wie diese Syntax in Python heißen würde :)
Hoffe das hilft,
Prost!
(EDIT Di Apr 9 20:57:30 2013) Nun, ich glaube, ich habe endlich herausgefunden, worum es bei diesen eckigen Klammern in Einzeilern geht. sie sind "Listenverständnisse" (anscheinend); Beachten Sie dies zuerst in 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>
Der Befehl in runden Klammern / Klammern wird also als "Generatorobjekt" angesehen. Wenn wir es durch Aufrufen "durchlaufen", wird next()
der Befehl in der Klammer ausgeführt (beachten Sie das "abc" in der Ausgabe):
$ 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>
Wenn wir jetzt eckige Klammern verwenden, müssen Sie nicht aufrufen next()
, damit der Befehl ausgeführt wird. Er wird sofort nach der Zuweisung ausgeführt. jedoch zeigt spätere Untersuchung , dass a
ist None
:
$ echo $STR | python -c "import sys,re; a=[sys.stdout.write(line) for line in sys.stdin]; print a"
abc
[None]
Dies lässt nicht viele Informationen zu suchen, für den Fall der eckigen Klammern - aber ich bin auf diese Seite gestoßen, die meiner Meinung nach erklärt:
Python Tipps und Tricks - Erste Ausgabe - Python Tutorials | Dream.In.Code :
Wenn Sie sich erinnern, ist das Standardformat eines Generators für eine einzelne Zeile eine Art 'for'-Schleife in Klammern. Dadurch wird ein iterierbares "One-Shot" -Objekt erstellt, über das Sie nur in eine Richtung iterieren können und das Sie am Ende nicht mehr verwenden können.
Ein 'Listenverständnis' sieht fast genauso aus wie ein normaler einzeiliger Generator, außer dass die regulären Klammern - () - durch eckige Klammern - [] ersetzt werden. Der Hauptvorteil des alistischen Verständnisses besteht darin, dass eine "Liste" anstelle eines "einmaligen" iterierbaren Objekts erstellt wird, sodass Sie es durchgehen, Elemente hinzufügen, sortieren usw. können.
Und in der Tat ist es eine Liste - es ist nur das erste Element, das zu keinem wird, sobald es ausgeführt wird:
$ 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
Listenverständnisse sind ansonsten in 5. Datenstrukturen: 5.1.4 dokumentiert . Listenverständnisse - Python v2.7.4-Dokumentation als "Listenverständnisse bieten eine übersichtliche Möglichkeit zum Erstellen von Listen"; vermutlich kommt hier die eingeschränkte "Ausführbarkeit" von Listen in Einzeilern ins Spiel.
Nun, ich hoffe, ich bin hier nicht zu daneben ...
EDIT2: und hier ist eine einzeilige Befehlszeile mit zwei nicht verschachtelten for-Schleifen; beide in eckigen Klammern "Listenverständnis" eingeschlossen:
$ 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]
Beachten Sie, dass die zweite "Liste" b
jetzt zwei Elemente enthält, da ihre for-Schleife explizit zweimal ausgeführt wurde. Das Ergebnis von war jedoch sys.stdout.write()
in beiden Fällen (anscheinend) None
.