tutorial - Forma más Pythonic equivalente para: while((x=next())!=END)
web scraping python (7)
¿Cuál es el mejor modismo de Python para este constructo C?
while ((x = next()) != END) {
....
}
No tengo la capacidad de recodificar next ().
actualización: y la respuesta de parece ser:
for x in iter(next, END):
....
¿Puede proporcionar más información sobre lo que está tratando de lograr? No me queda claro por qué no puedes decir simplemente
for x in everything():
...
y hacer que la función todo devuelva todo, en lugar de escribir una función siguiente para simplemente devolver una cosa a la vez. Los generadores pueden incluso hacer esto de manera bastante eficiente.
¿Qué está tratando de hacer aquí? Si está iterando sobre una lista, puede usar for e in L
donde e es el elemento y L es la lista. Si está filtrando una lista, puede usar la lista de comprensión (es decir, [ e for e in L if e % 2 == 0 ]
para obtener todos los números pares en una lista).
Depende un poco de lo que quieras hacer. Para hacer coincidir su ejemplo lo más posible, crearía un generador e iteraría sobre él:
def next():
for num in range(10):
yield num
for x in next():
print x
Respuesta corta: no hay forma de hacer una asignación de variable en línea en un ciclo while en Python. Lo que significa que no puedo decir:
while x=next():
// do something here!
Como eso no es posible, existen varias formas "idiomáticamente correctas" de hacer esto:
while 1:
x = next()
if x != END:
// Blah
else:
break
Obviamente, esto es feo. También puede usar uno de los enfoques de "iterador" enumerados anteriormente, pero, nuevamente, eso puede no ser ideal. Finalmente, puedes utilizar el enfoque de "bolsillo de pita" que acabo de encontrar mientras busco en Google:
class Pita( object ):
__slots__ = (''pocket'',)
marker = object()
def __init__(self, v=marker):
if v is not self.marker:
self.pocket = v
def __call__(self, v=marker):
if v is not self.marker:
self.pocket = v
return self.pocket
Ahora puedes hacer:
p = Pita()
while p( next() ) != END:
// do stuff with p.pocket!
Gracias por esta pregunta; aprender sobre el idioma __call__
fue realmente genial! :)
EDITAR: Me gustaría dar crédito donde se debe crédito. El idioma ''pita pocket'' fue encontrado aquí
Si necesita hacer esto más de una vez, la vía pythonic usaría un iterador
for x in iternext():
do_something_with_x
donde iternext
se definiría usando algo así como (¡ explícito es mejor que implícito! ):
def iternext():
x = next()
while x != END:
yield x
x = next()
Tal vez no sea terriblemente idiomático, pero me inclinaría a ir con
x = next()
while x != END:
do_something_with_x
x = next()
... pero eso es porque encuentro ese tipo de cosas fáciles de leer
@La respuesta de Mark Harrison:
for x in iter(next_, END):
....
Aquí hay un extracto de la documentación de Python :
iter(o[, sentinel])
Devuelve un objeto iterador. ... (snip) ... Si el segundo argumento,
sentinel
, se da, entonceso
debe ser un objeto invocable. El iterador creado en este caso invocaráo
sin argumentos para cada llamada a su métodonext()
; si el valor devuelto es igual asentinel
, seStopIteration
; de lo contrario, se devolverá el valor.