2012-05-12 17 views
12

Czy poniższy kod jest złą praktyką?Czy python oficjalnie obsługuje ponowne użycie zmiennej pętli po pętli?

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

Jakoś czuje do mnie jak zmiennej i powinny pozostać w zakresie do bloku wewnątrz pętli for. Jednak Python 2.7 pozwala mi ponownie użyć go po pętli.

Czy python oficjalnie obsługuje tę funkcję, czy też nadużywam tego języka?

+0

hmmm ... Wygląda na to może być ok, ponieważ jest on używany [tutaj] (http://stackoverflow.com/questions/2138873/cleanest-way-to-get-last-item-from-python-iterator) – jamylak

+1

Istnieje spora liczba przypadków użycia, które korzystają z dostępu do ostatniej wartości zmiennej pętli w kolejnym kodzie –

Odpowiedz

12

Tak, to oficjalne:

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

Uwaga że target list po for jest znacznie więcej niż tylko zmiennej:

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

itp Takie rzeczy nie mogą po prostu zniknąć po pętla.

0

To nie jest funkcja. Jak pisałeś, zmienna pozostaje w zakresie. To normalne zachowanie tłumacza.

+2

Hmm, Zignorowałem to, ponieważ "to nie jest funkcja", wydaje się bezpośrednio zaprzeczać najwyższej odpowiedzi, ale teraz ponownie czytam pytanie, które myślę, że masz na myśli "to nie jest funkcja, która" trwa "tylko dla zakresu pętli", co jest prawdą.Opuszczę tam jednak stwierdzenie, ponieważ myślę, że twoje sformułowanie jest niejasne, a interpretacja, którą najpierw miałem, była bardziej naturalna (i zła). –

3

Python może wydawać się nieco wyjątkowy, jeśli chodzi o zakres, jeśli pochodzą z języków takich jak C lub Java. Jak poprzednia odpowiedź brzmi, kod jest absolutnie poprawny, ale polecam przeciw niemu. Tworzy niezbyt czytelny kod, a ponadto, jeśli some_values okaże się pusty, wystąpi wyjątek w ostatnim wierszu kodu.

Więc odpowiedź na twoje pytanie brzmi - tak, jest oficjalnie obsługiwana, ale w większości przypadków nie jest zalecaną strategią.

Interesującą dyskusję można znaleźć here, a także lokalną dyskusję na temat SO.

+0

Kto jej nie poleca? I dlaczego kod ten byłby trudny do odczytania - zmienne Pythona istnieją w całym zakresie, ale są one wprowadzane. – Marcin

+0

Zgadzam się. To po prostu wydaje się "brudne". – georg

+2

Przede wszystkim uważam, że przyjmuje założenie, że pętla jest uruchomiona, a zmienna rzeczywiście przypisana. Po drugie, gdybym czytał to jako trzecią osobę, zakładałbym zmienne zdefiniowane na tym samym/niższym wcięciu. Ale społeczność Pythona jest podzielona na tę. – petr

1

Tak jak powiedział @petr, brzmi to nienaturalnie. Nie dlatego, że dozwolone jest, że jest to naturalne lub musisz go używać.

raczej mam coś takiego, choć może nie mieć zastosowania do logiki z break użytkowej przypadku:

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

Ale to jeszcze podnieść NameError jeśli some_values ocenić opróżnić, ale brzmi wyraźniej. Nie daje wyraźnej czytelności wewnętrznego zakresu, ale może sugerować to wcięcie.

Ale jak powiedzieli inni, aby odpowiedzieć na konkretne pytanie PO, tak, to jest legalne.

2

Możesz użyć tej techniki do skanowania listy dla elementów pasujących pewne kryteria:

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

handle(item) 
Powiązane problemy