2012-05-12 9 views
12

¿El siguiente código es una mala práctica?¿Admite oficialmente python la reutilización de una variable de bucle después del bucle?

for i in some_values: 
    do_whatever(i) 
do_more_things(i) 

De alguna manera, se siente a mí como la variable i debe permanecer en el ámbito de la manzana en el interior del bucle para. Sin embargo, Python 2.7 me permite reutilizarlo después del ciclo.

¿Python oficialmente admite esa característica, o estoy abusando del idioma?

+0

hmmm ... parece que esto podría ser aceptable ya que se utiliza [aquí] (http://stackoverflow.com/questions/2138873/cleannest-way-to-get-last-item-from-python-iterator) – jamylak

+1

Hay un buen número de casos de uso que se benefician al acceder al último valor de una variable de bucle en el siguiente código –

Respuesta

12

Sí, es oficial:

for_stmt ::= "for" target_list "in" expression_list ":" suite 
       ["else" ":" suite] 

> The target list is not deleted when the loop is finished 

http://docs.python.org/reference/compound_stmts.html#for

Tenga en cuenta que una target list después for es mucho más que sólo una variable:

for some_list[blah] in... 
for some_object.foo in... 
for a[:n] in ...: 

etc. Estas cosas no pueden simplemente desaparecer después el lazo.

0

Eso no es una característica. Como escribiste, la variable permanece en el alcance. Es un comportamiento de intérprete normal.

+2

Hmm, He votado negativamente porque "Eso no es una característica" parece contradecir directamente la respuesta principal, pero ahora volviendo a leer la pregunta que creo que quiere decir "no es una característica que' yo 'solo dure el alcance del ciclo ", lo cual es cierto.Sin embargo, voy a dejar el voto negativo allí, porque creo que su redacción no está clara y la interpretación que primero tuve fue la más natural (y errónea). –

3

Python puede sentirse un poco especial cuando se trata de determinar el alcance si vienes de idiomas como C o Java. Como dice la respuesta anterior, el código es absolutamente válido, pero recomendaría no hacerlo. No crea un código especialmente legible y, además, si some_values resulta estar vacío, se generará una excepción en la última línea del código.

Así que la respuesta a su pregunta es: sí, es oficialmente compatible, pero en la mayoría de los casos no es una estrategia recomendada.

Se puede encontrar una discusión interesante en here y también en el debate local en SO.

+0

¿Quién no lo recomienda? Y por qué haría que el código fuera difícil de leer: las variables de Python existen en todo su alcance, sin embargo, se introducen. – Marcin

+0

Estoy de acuerdo. Simplemente se siente "sucio". – georg

+2

En primer lugar, creo que supone que el ciclo se ejecuta y la variable efectivamente asignada. En segundo lugar, al leer esto como una tercera persona, asumiría las variables definidas en la misma sangría/inferior. Pero la comunidad de Python está dividida en este. – petr

1

Al igual que @petr dijo, parece antinatural. No porque esté permitido que sea natural o que tenga que usarlo.

preferiría tener algo como esto, a pesar de que no se aplique a la lógica con un break de casos de uso:

for i in some_values: 
    do_whatever(i) 
else: 
    do_more_things(i)

Pero esto todavía aumentar si NameErrorsome_values evaluar a vaciar, pero suena más clara. No da la legibilidad clara de un alcance interno, pero la sangría puede sugerirlo.

Pero como otros dicen, para responder a la pregunta específica del OP, sí, es legal.

2

Puede utilizar esta técnica para explorar una lista de elementos que coinciden con algunos criterios:

for item in iter: 
    if interesting(item): 
     break 
else: 
    raise ValueError('iter is boring.') 

handle(item) 
Cuestiones relacionadas