Вопрос:

перебор файлового объекта в Python не работает, но readlines () работает, но неэффективно

python

2016 просмотра

3 ответа

593 Репутация автора

В следующем коде, если я использую:

for line in fin:

Выполняется только для «а»

Но если я использую:

wordlist = fin.readlines()
for line in wordlist:

Затем он выполняется в течение Z.

Но readlines()читает весь файл сразу, чего я не хочу.

Как этого избежать?

def avoids():
    alphabet = 'abcdefghijklmnopqrstuvwxyz'
    num_words = {}

    fin = open('words.txt')

    for char in alphabet:
      num_words[char] = 0
      for line in fin:
        not_found = True
        word = line.strip()
        if word.lower().find(char.lower()) != -1:
          num_words[char] += 1
    fin.close()
    return num_words
Автор: Greg Lafrance Источник Размещён: 07.11.2012 07:10

Ответы (3)


8 плюса

226563 Репутация автора

Решение

синтаксис for line in finможет быть использован только один раз. После того, как вы это сделаете, вы исчерпали файл и не сможете прочитать его снова, пока не «сбросите указатель файла» fin.seek(0). И наоборот, fin.readlines()даст вам список, который вы можете повторять снова и снова.


Я думаю, что простой рефакторинг с Counter(python2.7 +) может избавить вас от этой головной боли:

from collections import Counter
with open('file') as fin:
    result = Counter()
    for line in fin:
        result += Counter(set(line.strip().lower()))

который будет подсчитывать количество слов в вашем файле (1 слово в строке), которые содержат определенный символ (это то, во что я верю вашему исходному коду ... Пожалуйста, исправьте меня, если я ошибаюсь)

Вы также можете легко сделать это с помощью defaultdict(python2.5 +):

from collections import defaultdict
with open('file') as fin:
    result = defaultdict(int)
    for line in fin:
        chars = set(line.strip().lower())
        for c in chars:
            result[c] += 1

И, наконец, пиная его старой школы - я даже не знаю, когда setdefaultбыл представлен ...:

fin = open('file')
result = dict()
for line in fin:
    chars = set(line.strip().lower())
    for c in chars:
        result[c] = result.setdefault(c,0) + 1

fin.close()
Автор: mgilson Размещён: 07.11.2012 07:12

5 плюса

622054 Репутация автора

У вас есть три варианта:

  1. В любом случае прочитайте весь файл.
  2. Обратитесь к началу файла, прежде чем пытаться повторить его снова.
  3. Перестройте ваш код, чтобы он не перебирал файл более одного раза.
Автор: Ignacio Vazquez-Abrams Размещён: 07.11.2012 07:12

0 плюса

19773 Репутация автора

Пытаться:

from collections import defaultdict
from itertools import product

def avoids():
    alphabet = 'abcdefghijklmnopqrstuvwxyz'

    num_words = defaultdict(int)

    with open('words.txt') as fin:
        words = [x.strip() for x in fin.readlines() if x.strip()]

    for ch, word in product(alphabet, words):
        if ch not in word:
             continue
        num_words[ch] += 1

    return num_words
Автор: Artsiom Rudzenka Размещён: 07.11.2012 07:16
Вопросы из категории :
32x32