(respondeu em 23 de novembro de 2010 às 19:48)
Eu não sou realmente um grande Pythoner - mas encontrei essa sintaxe uma vez, esqueci de onde, então pensei em documentá-la:
se você usar em sys.stdout.write
vez de print
( a diferença é que sys.stdout.write
aceita argumentos como uma função, entre parênteses - print
e não usa ), então para uma linha, você pode inverter a ordem do comando e for
remover o ponto e vírgula, e colocando o comando entre colchetes, ou seja:
python -c "import sys; [sys.stdout.write('rob\n') for r in range(10)]"
Não tenho idéia de como essa sintaxe seria chamada em Python :)
Espero que isto ajude,
Felicidades!
(EDIT terça-feira, 9 de abril, 20:57:30 2013) Bem, acho que finalmente encontrei o significado desses colchetes em uma linha; eles são "compreensões de lista" (aparentemente); observe primeiro no 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>
Portanto, o comando entre colchetes / parênteses é visto como um "objeto gerador"; se "iterarmos" chamando next()
- então o comando entre parênteses será executado (observe o "abc" na saída):
$ 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 agora usarmos colchetes - observe que não precisamos chamar next()
para que o comando seja executado, ele será executado imediatamente após a atribuição; no entanto, uma inspeção posterior revela que a
é None
:
$ echo $STR | python -c "import sys,re; a=[sys.stdout.write(line) for line in sys.stdin]; print a"
abc
[None]
Isso não deixa muita informação para procurar, no caso de colchetes - mas me deparei com esta página, que acho que explica:
Dicas e truques para Python - Primeira edição - Tutoriais em Python | Dream.In.Code :
Se você se lembra, o formato padrão de um gerador de linha única é um tipo de loop 'for' de uma linha entre colchetes. Isso produzirá um objeto iterável 'one-shot', que é um objeto que você pode repetir em apenas uma direção e que não pode ser reutilizado quando chegar ao fim.
Uma 'compreensão de lista' parece quase o mesmo que um gerador comum de uma linha, exceto que os colchetes regulares - () - são substituídos por colchetes - []. O principal avanço da compreensão alista é que produz uma 'lista', em vez de um objeto iterável 'one-shot', para que você possa ir e voltar através dele, adicionar elementos, classificar etc.
E, de fato, é uma lista - é apenas o primeiro elemento que não se torna assim que é executado:
$ 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
As compreensões da lista estão documentadas em 5. Estruturas de Dados: 5.1.4. Compreensões de lista - documentação do Python v2.7.4 como "Compreensões de lista fornecem uma maneira concisa de criar listas"; presumivelmente, é aí que a limitada "executabilidade" das listas entra em jogo em uma linha.
Bem, espero não estar muito errado aqui ...
EDIT2: e aqui está uma linha de comando de uma linha com dois for-loops não aninhados; ambos colocados entre colchetes "compreensão da lista":
$ 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]
Observe que a segunda "lista" b
agora tem dois elementos, já que seu loop for foi executado explicitamente duas vezes; no entanto, o resultado de sys.stdout.write()
ambos os casos foi (aparentemente) None
.