(ha risposto il 23 novembre 10 alle 19:48)
Non sono un grande Pythoner, ma ho trovato questa sintassi una volta, ho dimenticato da dove, quindi ho pensato di documentarlo:
se usi sys.stdout.write
invece di print
( la differenza è, sys.stdout.write
prende argomenti come una funzione, tra parentesi - mentre print
non lo fa ), quindi per una riga, puoi cavartela invertendo l'ordine del comando e for
rimuovendo il punto e virgola, e racchiudendo il comando tra parentesi quadre, ovvero:
python -c "import sys; [sys.stdout.write('rob\n') for r in range(10)]"
Non ho idea di come questa sintassi verrebbe chiamata in Python :)
Spero che questo ti aiuti,
Saluti!
(EDIT mar 9 aprile 20:57:30 2013) Beh, penso di aver finalmente trovato di cosa si tratta questa parentesi quadra in una riga; sono "comprensione delle liste" (apparentemente); prima nota questo 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>
Quindi il comando tra parentesi tonde / parentesi è visto come un "oggetto generatore"; se "iteriamo" attraverso di essa chiamando next()
- quindi verrà eseguito il comando tra parentesi (notare "abc" nell'output):
$ 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>
Se ora utilizziamo parentesi quadre - nota che non è necessario chiamare next()
per eseguire il comando, che viene eseguito immediatamente dopo l'assegnazione; tuttavia, un'ispezione successiva rivela che a
è None
:
$ echo $STR | python -c "import sys,re; a=[sys.stdout.write(line) for line in sys.stdin]; print a"
abc
[None]
Questo non lascia molte informazioni da cercare, nel caso delle parentesi quadre - ma mi sono imbattuto in questa pagina che penso spiega:
Python Tips And Tricks - Prima edizione - Python Tutorials | Codice Dream.In :
Se ricordi, il formato standard di un generatore a linea singola è una specie di loop "for" all'interno di parentesi. Questo produrrà un oggetto iterabile "one-shot" che è un oggetto su cui puoi scorrere in una sola direzione e che non puoi riutilizzare una volta raggiunta la fine.
Una "comprensione della lista" sembra quasi uguale a un normale generatore di una riga, tranne per il fatto che le parentesi regolari - () - sono sostituite da parentesi quadre - []. Il principale vantaggio della comprensione globale è che produce un 'elenco', piuttosto che un oggetto iterabile 'one-shot', in modo da poter andare avanti e indietro, aggiungere elementi, ordinare, ecc.
E infatti è un elenco - è solo il suo primo elemento che diventa nessuno non appena viene eseguito:
$ 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
La comprensione dell'elenco è altrimenti documentata in 5. Strutture di dati: 5.1.4. Comprensioni elenco: la documentazione di Python v2.7.4 come "Comprensioni elenco fornisce un modo conciso per creare elenchi"; presumibilmente, è qui che entra in gioco la limitata "eseguibilità" delle liste.
Beh, spero di non essere terribilmente troppo fuori dal segno qui ...
EDIT2: ed ecco una riga di comando di un liner con due for-loop non nidificati; entrambi racchiusi tra parentesi quadre "comprensione elenco":
$ 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]
Si noti che il secondo "elenco" b
ora ha due elementi, poiché il suo ciclo for è stato esplicitamente eseguito due volte; tuttavia, il risultato di sys.stdout.write()
in entrambi i casi è stato (apparentemente) None
.