2011-11-18 11 views
6

Pętlę przechodzę przez plik i jeśli coś znajdę, chciałbym przeczytać przed sobą kilka linii, szukając czegoś, zanim wróci kontrola do głównej pętli. Jednak chcę zwrócić kontrolę w punkcie, w którym przestałem patrzeć w przyszłość.Jak odczytywać wcześniej plik podczas przechodzenia przez niego za pomocą Pythona?

Przykładowy kod:

for line in file: 
    line = line.strip() 
    llist = line.split() 

    if llist[0] == 'NUMS': 
     # some loop to read ahead and print nums on their own line 
     # until it finds END, then return control to the main for 
     # loop at the point where it stopped looking ahead. 

Wejście próbki:

NUMS 
1 
2 
3 
4 
5 
END 
SOME 
MORE 
STUFF 
NUMS 
6 
7 
8 
9 
0 
END 

Pożądany wyjściowa:

1 2 3 4 5 
6 7 8 9 0 

Jestem dość nowy w Pythonie, więc jeśli istnieje lepszy sposób to zrobić oprócz używania pętli do patrzenia w przyszłość, cieszę się, że to widzę.

Odpowiedz

4

Po zapętleniu otwartych plików, można uzyskać tylko jedną linię dokładnie jeden raz. W przeciwieństwie do list, gdzie każda pętla for otrzyma własny iterator na całej liście.

Można mieć wewnętrzną pętlę „ukraść” wiersze z pliku, tak, że zewnętrzna pętla nie dostać je zobaczyć:

for line in file: 
    line = line.strip() 
    llist = line.split() 

    if llist and llist[0] == 'NUMS': 
     for line in file: 
      line = line.strip() 
      if line == 'END': 
       break 
      else: 
       print line, 
     print # newline 

Poczytaj na ten temat, jak iterators praca uzyskać więcej informacji.

+0

Więc wewnętrzne 'dla linii w pliku:' zaczyna się od linii, gdzie zewnętrzna została wyłączona? Myślałem, że zacznie się od początku pliku. – astay13

+2

@astay: To nie ma nic wspólnego z wewnętrzną/zewnętrzną. W tym kodzie jest dokładnie jeden iterator. 'dla rzeczy w ' po prostu wykonuje pętlę wokół następnej rzeczy, aż iterator podniesie StopIteration. Możesz wyjść z pętli i rozpocząć kolejną pętlę, która będzie kontynuowała otrzymywanie następnej rzeczy. –

+0

@John and Petr, Dzięki za pomoc w zrozumieniu plików/iteratorów lepiej! Wybieram to rozwiązanie, ponieważ mój kod wymagałby około 500 linii patrzenia w przyszłość. – astay13

4

Nie warto czytać dalej, jeśli nie jest to konieczne, co ma miejsce w tym przypadku. To, co musisz zrobić, można osiągnąć w pojedynczej pętli for, utrzymując jeden bit stanu. To pozwala na sprawdzanie błędów i skaluje się do znacznie bardziej skomplikowanych wymagań niż może być obsługiwane przez zagnieżdżone pętle nad tym samym iteratorem.

guff = """NUMS 
1 
2 
etc etc 
9 
0 
END""" 

state = "" 
for item in guff.split(): 
    if item == "NUMS": 
     if state == "NUMS": print "missing END" 
     state = "NUMS" 
    elif item == "END": 
     if state == "": print "missing NUMS" 
     state = "" 
     print 
    elif state == "NUMS": 
     print item, 

if state == "NUMS": print # missing END 
Powiązane problemy