在Python中迭代文件对象不起作用,但readlines()确实有效但效率低下

Gre*_*nce 3 python

在以下代码中,如果我使用:

for line in fin:
Run Code Online (Sandbox Code Playgroud)

它只执行'a'

但如果我使用:

wordlist = fin.readlines()
for line in wordlist:
Run Code Online (Sandbox Code Playgroud)

然后它执行直通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
Run Code Online (Sandbox Code Playgroud)

mgi*_*son 8

语法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()))
Run Code Online (Sandbox Code Playgroud)

它会计算你文件中包含特定字符的单词数量(每行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
Run Code Online (Sandbox Code Playgroud)

最后,踢它老派 - 我甚至不知道什么时候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()
Run Code Online (Sandbox Code Playgroud)


Ign*_*ams 5

你有三个选择:

  1. 无论如何,请阅读整个文件.
  2. 在尝试再次迭代之前,回到文件的开头.
  3. 重新构建代码,使其不需要多次迭代文件.