(respondió el 23 de noviembre de 2010 a las 19:48)
No soy realmente un gran Pythoner, pero una vez encontré esta sintaxis, olvidé de dónde, así que pensé en documentarla:
si usa en sys.stdout.write
lugar de print
( la diferencia es, sys.stdout.write
toma argumentos como una función, entre paréntesis, mientras print
que no lo hace ), entonces, para una línea, puede salirse invirtiendo el orden del comando y for
, quitando el punto y coma, y encerrando el comando entre corchetes, es decir:
python -c "import sys; [sys.stdout.write('rob\n') for r in range(10)]"
No tengo idea de cómo se llamaría esta sintaxis en Python :)
Espero que esto ayude,
¡Salud!
(EDITAR el martes 9 de abril 20:57:30 2013) Bueno, creo que finalmente encontré de qué se tratan estos corchetes en una sola línea; son "listas de comprensiones" (aparentemente); primera nota esto en 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>
Entonces el comando entre paréntesis / paréntesis se ve como un "objeto generador"; si "iteramos" a través de él al llamar next()
, se ejecutará el comando dentro del paréntesis (observe el "abc" en la salida):
$ 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>
Si ahora usamos corchetes, tenga en cuenta que no necesitamos llamar next()
para ejecutar el comando, se ejecuta inmediatamente después de la asignación; sin embargo, una inspección posterior revela que a
es None
:
$ echo $STR | python -c "import sys,re; a=[sys.stdout.write(line) for line in sys.stdin]; print a"
abc
[None]
Esto no deja mucha información para buscar, para el caso de los corchetes, pero me topé con esta página que creo explica:
Consejos y trucos de Python - Primera edición - Tutoriales de Python | Dream.In.Code :
Si recuerda, el formato estándar de un generador de una sola línea es una especie de bucle 'for' de una línea dentro de los corchetes. Esto producirá un objeto iterativo 'one-shot' que es un objeto sobre el que puede iterar en una sola dirección y que no puede reutilizar una vez que llegue al final.
Una 'comprensión de lista' se ve casi igual que un generador de una línea regular, excepto que los corchetes regulares (() se reemplazan por corchetes - []. El mayor avance de la comprensión de la lista es que produce una 'lista', en lugar de un objeto iterable 'de una sola vez', para que pueda ir y venir a través de él, agregar elementos, ordenar, etc.
Y, de hecho, es una lista: es solo que su primer elemento se convierte en ninguno tan pronto como se ejecuta:
$ 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
Las comprensiones de las listas se documentan en 5. Estructuras de datos: 5.1.4. Lista de comprensiones: la documentación de Python v2.7.4 como "Las comprensiones de listas proporcionan una forma concisa de crear listas"; presumiblemente, ahí es donde entra en juego la limitada "ejecubilidad" de las listas en una sola línea.
Bueno, espero no estar demasiado fuera de lugar aquí ...
EDIT2: y aquí hay una línea de comando de una línea con dos bucles for no anidados; ambos encerrados entre corchetes de "comprensión de la 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 la segunda "lista" b
ahora tiene dos elementos, ya que su ciclo for se ejecutó explícitamente dos veces; sin embargo, el resultado de sys.stdout.write()
en ambos casos fue (aparentemente) None
.