在for循环中使用if语句时列出索引超出范围错误

时间:2016-08-13 22:46:50

标签: python python-2.7

我是python的新手;我一直在使用javascript进行编码,因此我并不习惯所有错误。

我尝试使用for循环向空对象添加属性,但是我收到错误,说列表索引超出范围。当我在for循环中添加if语句时,似乎发生了错误。我虽然没有使用索引来遍历seat_info数组。请帮助我理解为什么会这样,谢谢!

    seats_info = ['\n1,133,0,A', '\n1,133,2,C', '\n1,133,1,B', '\n1,133,4,E', '\n1,133,3,D', '\n2,132,0,24', '\n2,132,1,25', '\n2,132,2,26']

    def read_manifest(self, manifest):
    file = manifest_dir + '/' + manifest
    data = open(file, 'r')
    seats_info = data.read().split('\r')[1:]
    data.close()

    self.seat_information = {}
    for seat_info in seats_info:
        one_seat = seat_info.split(',')
        section_id = one_seat[0][1:]
        one_seat.remove(one_seat[0])
        one_seat.insert(0, section_id)

        if one_seat[1] not in self.seat_information:
            self.seat_information[one_seat[1]] = [one_seat]
        else:
            self.seat_information[one_seat[1]].append(one_seat)


      Error Message that I received 

      Traceback (most recent call last):
      File "path/normalizer.py", line 75, in <module>
normalizer.read_manifest(citifield)
      File "path/normalizer.py", line 36, in read_manifest
     if one_seat[1] not in self.seat_information:
     IndexError: list index out of range

2 个答案:

答案 0 :(得分:0)

在数据文件中插入一个空白行以重现错误。

section_id = one_seat[0][1:]
one_seat[0] = section_id

此时,one_seat = [&#39;&#39;],因此没有one_seat [1]

if one_seat[1] ...

因此正确地提出了列表索引超出范围。

相反,当您使用硬编码索引时,您可能需要验证您的假设是否成立。以下是重写的示例:

def execute():
    seats_info = ['\n', '\n1,133,0,A', '\n1,133,2,C', '\n1,133,1,B', '\n1,133,4,E', '\n1,133,3,D', '\n2,132,0,24', '\n2,132,1,25', '\n2,132,2,26']
    for seat_info in seats_info:
        one_seat = seat_info.split(',')
        if len(one_seat):
            section_id = one_seat[0][1:]
            one_seat[0] = section_id
            # maybe check for a legal section_id here?
            if len(one_seat) > 1:
                row_id = one_seat[1]                
                if row_id not in seat_information:
                    seat_information[row_id] = [one_seat]
                else:
                    seat_information[row_id].append(one_seat)


seat_information = {}
execute()
for row, seats in seat_information.items():
    print "row", row
    for seat in seats:
        print "seat:", seat

答案 1 :(得分:-1)

虽然Kenny Ostrom的解决方案很好,但我实际上建议在读取数据文件后对其进行预处理。这样,您就不必经常检查假设并简化代码。具体来说,我有以下几点:

seats_info = ['\n', '\n1,133,0,A', '\n1,133,2,C', '\n1,133,1,B', '\n1,133,4,E', '\n1,133,3,D', '\n2,132,0,24', '\n2,132,1,25', '\n2,132,2,26']

#remove new line and other markup characters
seats_info = [str.strip(s) for s in seats_info]

#remove elements that have no content:     
seats_info = [s for s in seats_info if len(s)>0] 

现在,seats_info更清洁,不会向您抛出错误:

In [21]: seats_info
Out[21]:
['1,133,0,A',
 '1,133,2,C',
 '1,133,1,B',
 '1,133,4,E',
 '1,133,3,D',
 '2,132,0,24',
 '2,132,1,25',
 '2,132,2,26']

由于您目前正在索引\n,但现在您不必这样做,您必须将数据提取循环简化为:

for seat_info in seats_info:
    one_seat = seat_info.split(',')
    section_id = one_seat[0]

    if one_seat[1] not in seat_information:
        self.seat_information[one_seat[1]] = [one_seat]
    else:
        self.seat_information[one_seat[1]].append(one_seat)

最后,我强烈建议您使用with语句来读取数据,因为这样会更容易看到,而且我会说更多Pythonic。具体来说,请考虑read_manifest函数的以下定义:

def read_manifest(self, manifest):
    file = manifest_dir + '/' + manifest

    #read in the file:
    with open(file, 'r') as f:
        #because we later use str.strip, you don't need to do [1:] to get rid of \r
        seats_info = f.read().split('\r')

    #pre-process:
    seats_info = [str.strip(s) for s in seats_info]     
    seats_info = [s for s in seats_info if len(s)>0]