2016-08-07 2 views
-1

У меня есть этот .txt файл:Python для цикла с модификацией iterationlist

king james version of the bible 
the first book of moses called genesis 

Я использую питон-скрипт для статистики по .txt файлов, файл считывается в список final_list, а затем я выполнить этот код (часть более длинного сценария):

for word in final_list: 
    output_list.append((word,final_list.count(word))) 

    final_list[:] = [x for x in final_list if x != word] 
    #DEBUGGING 
    print(len(final_list)) 
    print(final_list) 

Моя проблема заключается в том, что некоторые из моего списка не используется для петли, которые я подозреваю, форма смотрит на выходе:

12 
['james', 'version', 'of', 'the', 'bible', 'the', 'first', 'book', 'of', 'moses', 'called', 'genesis'] 
11 
['james', 'of', 'the', 'bible', 'the', 'first', 'book', 'of', 'moses', 'called', 'genesis'] 
9 
['james', 'of', 'bible', 'first', 'book', 'of', 'moses', 'called', 'genesis'] 
8 
['james', 'of', 'bible', 'book', 'of', 'moses', 'called', 'genesis'] 
6 
['james', 'bible', 'book', 'moses', 'called', 'genesis'] 
5 
['james', 'bible', 'book', 'moses', 'called'] 

Это заставляет меня задаться вопросом, как работает python for-loop.

+4

Ваш код является очень неэффективным способом подсчета частот слов. Посмотрите на 'collections.Counter()', который сделает работу для вас проще и быстрее. –

+0

Спасибо, я посмотрю. Тем не менее, я думаю, что это не проблема с последними 5 словами, которые не повторяются, не так ли? –

+3

Никогда не изменяйте список, который вы повторяете. Поведение не определено. – Daniel

ответ

1

Проблема в том, что вы изменяете список. После первой итерации итератор Python перестает смотреть на «позицию 0» в списке и переходит в «положение 1.» Вы удалили элемент изначально в позиции 0 (king), поэтому элемент, который раньше находился в позиции 1 (james), теперь находится в положении 0, а это означает, что когда Python смотрит на элемент в позиции 1, он видит элемент, который был первоначально в позиции 2 (version).

В конце концов, итератор Python переместился в позицию, которая находится за пределами списка, поэтому она завершается так, как вы считаете, преждевременным, хотя это именно то, что вы просили.

+0

Это имеет смысл, спасибо. –

2

Вы не должны изменять список, который вы выполняете внутри цикла for. В противном случае вы получите такое странное поведение. Вам лучше использовать копию final_list likeso:

final_copy = final_list[:] 
for word in final_list: 
    output_list.append((word,final_copy.count(word))) 
    final_copy = [x for x in final_copy if x != word] 
+0

Хорошо, хотя в этом случае в 'output_list' будет несколько экземпляров нескольких слов. –

Смежные вопросы