1

对python非常陌生,无法理解为什么这不起作用。我在文本文件中逐行存储了一个网址列表。我想将前 10 个存储在一个名为 bing 的数组/列表中,接下来的 10 个存储在一个名为 yahoo 的列表中,最后 10 个存储在一个名为 dadgo 的列表中。我正在使用该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

4 回答 4

5

readlines用于读取文件。readlines一次读取所有行,因此第一次通过循环时,您会耗尽整个文件并将结果存储在bing. 然后,每次通过循环时,您都会用下一次调用的(空)结果覆盖bingyahoo或。所以你的清单最后都是空的。duckgoreadlines

有很多方法可以解决这个问题。除其他事项外,您应该考虑一次读取文件一行,使用readline(no '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]

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

于 2012-06-20T00:09:55.697 回答
1

readlines()读取文件的所有行。如果你再次调用它,你会得到空列表。因此,当您遍历循环时,您正在用空数据覆盖列表。

于 2012-06-20T00:09:43.930 回答
1

你应该使用readline()而不是readlines()

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

于 2012-06-20T00:11:04.533 回答
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()返回一个迭代器,我们必须将它显式地扩展为 a list,将其包裹在list().

我认为这是最简单的方法。它完美地表达了我们想要的:对于每一个,我们想要一个包含文件中 10 行的列表。完全不用专柜,每次拉10条线就行了!

编辑:现在使用额外行的检查,it.islice(f, 1)以便它只会拉一行。即使多出一行就足以知道有超过 30 行预期的行,这样如果有人不小心在一个非常大的文件上运行此代码,它就不会尝试将整个文件吞入内存。

于 2012-06-20T01:06:38.177 回答