从文本文件读入python列表

时间:2012-06-20 00:02:39

标签: python arrays list loops file-io

python非常新,无法理解为什么这不起作用。我有一个在文本文件中逐行存储的Web地址列表。我想将前10个存储在名为bing的数组/列表中,将下一个10存储在名为yahoo的列表中,将最后10个存储在名为duckgo的列表中。我正在使用readlines函数将文件中的数据读入每个数组。问题是没有写入列表。计数正在增加。此外,如果我完全删除循环并只是将整个文本文件读入一个列表,它可以完美地工作。这让我相信循环导致问题。我正在使用的代码如下。非常感谢一些反馈。

count=0;

#Open the file
fo=open("results.txt","r")

#read into each array
while(count<30):
    if(count<10):
        bing = fo.readlines()
        count+=1
        print bing
        print count

    elif(count>=10 and count<=19):
        yahoo = fo.readlines()
        count+=1
        print count

    elif(count>=20 and count<=29):
        duckgo = fo.readlines()
        count+=1
        print count

print bing
print yahoo
print duckgo

fo.close

4 个答案:

答案 0 :(得分:5)

您正在使用readlines来阅读文件。 readlines一次读取所有行,所以第一次通过循环时,耗尽整个文件并将结果存储在bing中。然后,每次循环时,您都会使用下一个bing调用的(空)结果覆盖yahooduckgoreadlines。所以你的清单一直都是空的。

有很多方法可以解决这个问题。除此之外,你应该考虑一次读取一行文件,readline(没有's)。或者更好的是,您可以逐行遍历文件,只需使用for循环:

for line in fo:
    ...

要保留当前代码的结构,您可以使用enumerate

for line_number, line in enumerate(fo):
    if condition(line_number):
        ...

但坦率地说,我认为你应该抛弃你现有的系统。一种更简单的方法是在没有循环的情况下使用readlines,并对结果列表进行切片!

lines = fo.readlines()
bing = lines[0:10]
yahoo = lines[10:20]
duckgo = lines[20:30]

还有很多其他方法可以做到这一点,有些可能会更好,但没有一种更简单!

答案 1 :(得分:1)

readlines()读取文件的所有行。如果再次调用它,则会显示空列表。因此,当您遍历循环时,您将使用空数据覆盖列表。

答案 2 :(得分:1)

您应该使用readline()代替readlines()

readlines()一次读取整个文件,而readline()从文件中读取一行。

答案 3 :(得分:1)

我建议你这样重写:

bing = []
yahoo = []
duckgo = []
with open("results.txt", "r") as f:
    for i, line in enumerate(f):
        if i < 10:
            bing.append(line)
        elif i < 20:
            yahoo.append(line)
        elif i < 30:
            duckgo.append(line)
        else:
            raise RuntimeError, "too many lines in input file"

请注意我们如何使用enumerate()获取行的运行计数,而不是自己生成count变量并需要自己递增。这在Python中被认为是好的风格。

但我认为解决此问题的最佳方法是使用itertools,如下所示:

import itertools as it
with open("results.txt", "r") as f:
    bing = list(it.islice(f, 10))
    yahoo = list(it.islice(f, 10)) 
    duckgo = list(it.islice(f, 10))
    if list(it.islice(f, 1)):
        raise RuntimeError, "too many lines in input file"

itertools.islice()(或it.islice(),因为我执行了import itertools as it)将从迭代器中提取指定数量的项目。我们的打开文件句柄对象f是一个从文件返回行的迭代器,因此it.islice(f, 10)从输入文件中提取10行。

由于it.islice()会返回迭代器,因此我们必须将其展开到list,并将其展开到list()

我认为这是最简单的方法。它完美地表达了我们想要的东西:对于每一个,我们想要一个包含10行文件的列表。根本没有必要保留一个计数器,每次只需拉10行!

编辑:检查额外的行现在使用it.islice(f, 1),这样它只会拉一行。甚至一条额外的行足以知道不仅仅有30条预期的行,这样如果有人在一个非常大的文件上意外地运行了这段代码,它就不会试图将整个文件淹没到内存中。