简体   繁体   English

读取文件时出现“ IndexError:列表索引超出范围”

[英]“IndexError: list index out of range” when reading file

Just started learning Python and I'm struggling with this a little. 刚开始学习Python时,我为此感到困惑。

I'm opening a txt file that will be variable in length and I need to iterate over a user definable amount of lines at a time. 我正在打开一个txt文件,该文件的长度是可变的,我需要一次遍历用户可定义的行数。 When I get to the end of the file I receive the error in the subject field. 当我到达文件末尾时,在主题字段中收到错误消息。 I've also tried the readlines() function and a couple of variations on the "if" statement that causes the problem. 我还尝试了readlines()函数以及导致问题的“ if”语句的一些变体。 I just can't seem to get the code to find EOF. 我只是似乎无法获得找到EOF的代码。

Hmm, as I write this, I'm thinking ... do I need to addlist "EOF" to the array and just look for that? 嗯,当我写这篇文章的时候,我在想...我是否需要将“ EOF”添加到数组中并寻找它? Is that the best solution, to find a custom EOF? 找到自定义的EOF是最好的解决方案吗?

My code snippet goes something like: 我的代码段如下所示:

### variables defined outside of scapy PacketHandler ##
x = 0
B = 0
##########

with open('dict.txt') as f:
    lines = list(f)
    global x
    global B
    B = B + int(sys.argv[3])
        while x <= B:
           while y <= int(sys.argv[2]): 
               if lines[x] != "":
                   #...do stuff...
                   # Scapy send packet Dot11Elt(ID="SSID",info"%s" %               (lines[x].strip()) 
                   # ....more code...
           x = x 1

Try a for in loop. 尝试for for循环。 You have created your list, now iterate through it. 您已经创建了列表,现在可以遍历列表。

with open('dict.txt') as f:
    lines = list(f)
    for item in lines: #each item here is an item in the list you created
        print(item)

this way you go through each line of your text file and don't have to worry about where it ends. 这样,您就可以遍历文本文件的每一行,而不必担心它的结尾。

edit: 编辑:

you can do this as well! 您也可以这样做!

with open('dict.txt') as f:
    for row in f:
        print(row)

Let's say you need to read X lines at a time, put it in a list and process it: 假设您需要一次读取X行,将其放入列表中并进行处理:

with open('dict.txt') as f:

    enoughLines = True  

    while enoughLines:
        lines = []

        for i in range(X):
            l = f.readline()
            if l != '':
                lines.append( l )
            else:
                enoughLines = False
                break

        if enoughLines:
            #Do what has to be done with the list “lines”
        else:
            break

#Do what needs to be done with the list “lines” that has less than X lines in it

The following function will return a generator that returns the next n lines in a file: 以下函数将返回一个生成器,该生成器返回文件中的后n行:

def iter_n(obj, n):
    iterator = iter(obj)
    while True:
        result = []
        try:
            while len(result) < n:
                result.append(next(iterator))
        except StopIteration:
            if len(result) == 0:
                raise
        yield result

Here is how you can use it: 使用方法如下:

>>> with open('test.txt') as f:
...     for three_lines in iter_n(f, 3): 
...         print three_lines
...
['first line\n', 'second line\n', 'third line\n']
['fourth line\n', 'fifth line\n', 'sixth line\n']
['seventh line\n']

Contents of test.txt: test.txt的内容:

first line
second line
third line
fourth line
fifth line
sixth line
seventh line

Note that, because the file does not have a multiple of 3 lines, the last value returned is not 3 lines, but just the rest of the file. 请注意,因为文件没有3行的倍数,所以最后返回的值不是3行,而是文件的其余部分。

Because this solution uses a generator, it doesn't require that the full file be read into memory (into a list), but iterates over it as needed. 由于此解决方案使用生成器,因此不需要将完整文件读入内存(进入列表),而是根据需要对其进行迭代。

In fact, the above function can iterate over any iterable object, like lists, strings, etc: 实际上,上面的函数可以迭代任何可迭代的对象,例如列表,字符串等:

>>> for three_numbers in iter_n([1, 2, 3, 4, 5, 6, 7], 3): 
...     print three_numbers
... 
[1, 2, 3]
[4, 5, 6]
[7]
>>> for three_chars in iter_n("1234567", 3): 
...     print three_chars
... 
['1', '2', '3']
['4', '5', '6']
['7']

If you want to get n lines in a list use itertools.islice yielding each list: 如果要在列表中获得n行,请使用itertools.islice产生每个列表:

from itertools import islice
def yield_lists(f,n):
    with open(f) as f:
        for sli in iter(lambda : list(islice(f,n)),[]):
            yield sli

If you want to use loops, you don't need a while loop at all, you can use an inner loop in range n-1 calling next on the file object with a default value of an empty string, if we get an empty string break the loop if not just append and again yield each list: 如果要使用循环,则根本不需要while循环,可以使用n-1范围内的内部循环,如果我们得到一个空字符串,则使用默认值空字符串在文件对象上调用next如果不只是追加就中断循环,并再次产生每个列表:

def yield_lists(f,n):
    with open(f) as f:
        for line in f:
            temp = [line]
            for i in range(n-1):
                line = next(f,"")
                if not line:
                    break
                temp.append(line)
            yield temp

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM