2015-07-11 1 views
8

Coś dziwnego dzieje się w tym kodzie:Dlaczego "the" przetrwać po .remove?

fh = open('romeo.txt', 'r') 
lst = list() 

for line in fh: 
    line = line.split() 
    for word in line: 
     lst.append(word) 

for word in lst: 
    numberofwords = lst.count(word) 
    if numberofwords > 1: 
     lst.remove(word) 

lst.sort() 

print len(lst) 
print lst 

romeo.txt pochodzi z http://www.pythonlearn.com/code/romeo.txt

Wynik:

27 
['Arise', 'But', 'It', 'Juliet', 'Who', 'already', 'and', 'breaks', 'east', 'envious', 'fair', 'grief', 'is', 'kill', 'light', 'moon', 'pale', 'sick', 'soft', 'sun', 'the', 'the', 'through', 'what', 'window', 'with', 'yonder'] 

Jak widać, istnieją dwa zwanej dalej ". Dlaczego? mogę uruchomić tę część kodu ponownie:

for word in lst: 
    numberofwords = lst.count(word) 
    if numberofwords > 1: 
     lst.remove(word) 

Po uruchomieniu tego kodu po raz drugi usuwa pozostałe zwanej dalej ", ale dlaczego nie działać po raz pierwszy?

poprawny wynik:

26 
['Arise', 'But', 'It', 'Juliet', 'Who', 'already', 'and', 'breaks', 'east', 'envious', 'fair', 'grief', 'is', 'kill', 'light', 'moon', 'pale', 'sick', 'soft', 'sun', 'the', 'through', 'what', 'window', 'with', 'yonder'] 
+0

dunnno dlaczego został edytowany trzeba przewinąć teraz zobaczyć result – Gunnm

+2

Domyślam się, że po '.remove()' pętla 'for' nie zapętla się poprawnie (ponieważ prawdopodobnie nie może poprawnie indeksować elementów). –

+4

Modyfikowanie listy podczas iteracji może prowadzić do niezdefiniowanego zachowania. –

Odpowiedz

14

W tej pętli:

for word in lst: 
    numberofwords = lst.count(word) 
    if numberofwords > 1: 
     lst.remove(word) 

lst zmienia się podczas iteracji nad nim. Nie rób tego. Prostą poprawką jest iteracja na jego kopii:

for word in lst[:]: 
+0

To działa. Wciąż nie wiem dokładnie, co się dzieje, ale dziękuję za szybką odpowiedź. – Gunnm

+3

@Gunnm Pamiętaj, aby nie modyfikować listy podczas jej powtarzania. Przyczyna tego prawdopodobnie staje się jasna, gdy dowiesz się więcej. –

+0

Yeah @Ivc już to wyczyściłem w komentarzu poniżej moje pytanie – Gunnm

6

Python udostępnia pyszne narzędzia do wykonywania tego rodzaju zadań. Za pomocą tego, co jest wbudowany, zazwyczaj można uniknąć rodzaje problemów widzisz z wyraźnymi pętli i modyfikację zmiennej pętli w miejscu:

with open('romeo.txt', 'r') as fh: 
    words = sorted(set(fh.read().replace('\n', ' ').split(' '))) 

print(len(words)) 
print(words) 
+0

Dzięki za udostępnienie kodu! Wciąż jestem nowym użytkownikiem Pythona, więc pracuję nawet z większością podstawowych metod, ale miło jest zobaczyć, jak bardzo możesz ulepszyć prosty kod. – Gunnm

+1

Nic złego w byciu początkującym! Zauważ, jak łatwo jest przeczytać, co dzieje się w powyższym kodzie. '.read() 'slurps zawartość pliku do jednego fragmentu tekstu. '.replace()' zmienia znaki nowej linii na spacje. '.split()' dzieli wszystko na słowa (spacje). 'set()' usuwa listę słów do unikalnych. 'sorted()' sortuje zestaw i zwraca listę (uporządkowaną). Nadzieja, która pomaga. –

+0

Yup. Naprawdę lubię uczyć się Pythona. – Gunnm