我使用for循环来读取文件,但我只想读取特定的行,比如第26行和第30行。是否有任何内置功能来实现这一点?


当前回答

def getitems(iterable, items):
  items = list(items) # get a list from any iterable and make our own copy
                      # since we modify it
  if items:
    items.sort()
    for n, v in enumerate(iterable):
      if n == items[0]:
        yield v
        items.pop(0)
        if not items:
          break

print list(getitems(open("/usr/share/dict/words"), [25, 29]))
# ['Abelson\n', 'Abernathy\n']
# note that index 25 is the 26th item

其他回答

如果你不介意导入,那么fileinput确实是你需要的(这是你可以读取当前行的行号)

file = '/path/to/file_to_be_read.txt'
with open(file) as f:
    print f.readlines()[26]
    print f.readlines()[30]

使用with语句打开文件,打印第26行和第30行,然后关闭文件。简单!

其中一些很可爱,但可以做得更简单:

start = 0 # some starting index
end = 5000 # some ending index
filename = 'test.txt' # some file we want to use

with open(filename) as fh:
    data = fin.readlines()[start:end]

print(data)

这将使用简单的列表切片,它加载整个文件,但大多数系统将适当地最小化内存使用,它比上面给出的大多数方法都快,并且适用于我的10G+数据文件。好运!

相当快,切中要害。

打印文本文件中的某些行。创建一个“lines2print”列表然后 当枚举“在”lines2print列表中时,只需打印。 要去除多余的'\n',请使用line.strip()或line.strip('\n')。 我只是喜欢“列表理解”,并尽可能地使用它。 我喜欢用“with”方法来读取文本文件,以防止 以任何理由打开文件。

lines2print = [26,30] # can be a big list and order doesn't matter.

with open("filepath", 'r') as fp:
    [print(x.strip()) for ei,x in enumerate(fp) if ei in lines2print]

或者如果list很小,只需在理解式中输入list作为列表。

with open("filepath", 'r') as fp:
    [print(x.strip()) for ei,x in enumerate(fp) if ei in [26,30]]

一个快速而紧凑的方法可以是:

def picklines(thefile, whatlines):
  return [x for i, x in enumerate(thefile) if i in whatlines]

它接受任何打开的类文件对象thefile(由调用者决定是否应该从磁盘文件打开,还是通过例如套接字或其他类文件流打开)和一组从零开始的行索引whatlines,并返回一个具有低内存占用和合理速度的列表。如果要返回的行数非常多,你可能更喜欢使用生成器:

def yieldlines(thefile, whatlines):
  return (x for i, x in enumerate(thefile) if i in whatlines)

这基本上只适用于循环——注意,唯一的区别是在return语句中使用圆括号而不是方括号,分别生成一个列表推导式和一个生成器表达式。

进一步注意,尽管提到了“行”和“文件”,但这些函数要通用得多——它们可以在任何可迭代对象上工作,无论是打开的文件还是其他文件,根据逐级递增的项号返回项的列表(或生成器)。所以,我建议使用更合适的通用名称;-)。