2009-02-12 14 views
12

Tengo la asignación de variable para devolver el valor asignado y compararlo con una cadena vacía, directamente en el ciclo while.¿Cómo hacer la asignación de variables dentro de un ciclo while (expresión) en Python?

Así es como lo estoy haciendo en PHP:

while((name = raw_input("Name: ")) != ''): 
    names.append(name) 

Lo que estoy tratando de hacer es idéntica a esta funcionalidad:

names = [] 
while(True): 
    name = raw_input("Name: ") 
    if (name == ''): 
     break 
    names.append(name) 

¿Hay alguna manera de hacer esto en Python?

Respuesta

14
from functools import partial 

for name in iter(partial(raw_input, 'Name:'), ''): 
    do_something_with(name) 

o si desea una lista:

>>> names = list(iter(partial(raw_input, 'Name: '), '')) 
Name: nosklo 
Name: Andreas 
Name: Aaron 
Name: Phil 
Name: 
>>> names 
['nosklo', 'Andreas', 'Aaron', 'Phil'] 
+0

+1 para una mejor solución para envolver un método existente. –

+0

No es una respuesta; Todavía no lo sé: ¿enlaza una variable en 'while' en Python? – Kaz

9

No, lo siento. Es un FAQ, explicado bien aquí:

En Pydocs, y Fredrik Lundh's blog.

La razón para no permitir la asignación en expresiones de Python es un error común, difícil de encontrar en esos otros lenguajes.

Se han propuesto muchas alternativas. La mayoría son hacks que ahorran algo de tipeo pero usan sintaxis o palabras clave arbitrarias o crípticas, y no cumplen el criterio simple para propuestas de cambio de idioma: debe sugerir intuitivamente el significado adecuado para un lector humano que aún no ha sido introducido en el constructo.

Un fenómeno interesante es que los programadores de Python más experimentados reconocen el modismo while True y no parece que le falte mucho la tarea de expresión en construcción; solo los recién llegados expresan un fuerte deseo de agregar esto al lenguaje.

Hay una forma alternativa de ortografía esto que parece atractiva:

line = f.readline() while line: 
    ... # do something with line... 
    line = f.readline() 
+0

este enlace parece no estar funcionando –

+0

Agregado enlace de actualización. ¡Gracias! –

+0

El enlace está muerto. – Makkes

12

se puede envolver raw_input() para convertirlo en un generador:

def wrapper(s): 
    while True: 
     result = raw_input(s) 
     if result = '': break 
     yield result 

names = wrapper('Name:') 

que significa que estamos de vuelta al punto uno pero con un código más complejo. Por lo tanto, si necesita ajustar un método existente, debe usar el enfoque nosklo.

+0

+1: Batirme por segundos. Sin embargo, agregue la definición de "raw_input como generador" a su respuesta. –

+0

¡Muchas gracias! La primera vez que utilizas el desbordamiento de pila por cierto, nunca supe que fue esta increíble, una respuesta perfecta en cuestión de minutos :) –

+0

¿Puedes detallar cómo "convertir raw_input en un generador" de una manera muy pitonica? – physicsmichael

1

estoy sólo 7 años de retraso, pero no hay otra solución. No es la mejor solución que se me ocurre, pero resalta un uso interesante de la excepción StopIteration. Puede hacer un ciclo similar para archivos/sockets de lectura de fragmentos y manejar tiempos de espera y cosas así.

names=[] 
try: 
    while True: 
     f = raw_input() 
     if not f: 
      raise StopIteration 
     else: 
      names.append(f) 
except StopIteration: 
    pass 

print names 
1
names = [] 
for name in iter(lambda: raw_input("Name: "), ''): 
    names.append(name) 
Cuestiones relacionadas