¿Cómo hacer la asignación de variables dentro de un bucle while (expresión) en Python?

Tengo la asignación de variable para devolver el valor asignado y compararlo con una cadena vacía, directamente en el bucle while.

Así es como lo estoy haciendo en PHP:

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

Lo que estoy tratando de hacer es idéntico a esto en funcionalidad:

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

¿Hay alguna manera de hacer esto en Python?

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

o si quieres una lista:

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

Puedes 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:') 

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

No lo siento. Es una FAQ, bien explicada aquí:

En Pydocs , y en el blog de Fredrik Lundh .

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

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

Un fenómeno interesante es que la mayoría de los progtwigdores de Python más reconocidos reconocen el while True lenguaje y no parece que les falte mucho la asignación en la expresión de construcción; Solo los recién llegados expresan un fuerte deseo de agregar esto al lenguaje.

Hay una forma alternativa de deletrear esto que parece atractiva:

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

Solo tengo 7 años de retraso, pero hay otra solución. No es la mejor solución que se me ocurre, pero destaca un uso interesante de la excepción StopIteration. Puede hacer un bucle similar para leer fragmentos de archivos / sockets y manejar los tiempos de espera y otras cosas muy bien.

 names=[] try: while True: f = raw_input() if not f: raise StopIteration else: names.append(f) except StopIteration: pass print names 
 names = [] for name in iter(lambda: raw_input("Name: "), ''): names.append(name) 

El PEP 572 propone Expresiones de asignación y ya ha sido aceptado. A partir de Python 3.8, podrás escribir:

 while name := input("Name: "): names.append(name) 

Citando la parte de la syntax y la semántica del PEP para algunos ejemplos más:

 # Handle a matched regex if (match := pattern.search(data)) is not None: # Do something with match # A loop that can't be trivially rewritten using 2-arg iter() while chunk := file.read(8192): process(chunk) # Reuse a value that's expensive to compute [y := f(x), y**2, y**3] # Share a subexpression between a comprehension filter clause and its output filtered_data = [y for x in data if (y := f(x)) is not None]