2016-08-13 37 views
0

我是python新手;我一直在JavaScript編碼,所以我不習慣我得到的所有錯誤。列表索引超出範圍錯誤,同時使用for循環中的if語句

我試圖用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 
+0

建議在此處僅使用print語句調試。文件格式可能會以一種微不足道的方式偏離您的期望。通過在你的循環中放置一個'print seat_info'或'print one_seat',你將會有更多的事情要做。 –

+0

Javascript也會在訪問超出數組索引時拋出錯誤,是嗎? –

+0

您有硬編碼的索引值,比如one_seat = seat_info.split(',') section_id = one_seat [0] [1:],並且seat_info.split(',')可能會返回一個數組範圍。檢查你的數據。建議在不確定的情況下使用try塊並處理異常 – slysid

回答

0

在數據文件中插入空白行以重現錯誤。

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

此時,one_seat = [ ''],所以沒有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

雖然肯尼·奧斯特羅姆的解決方案是很好,我真的建議預處理的數據文件中讀取它通過這種方式後,你就不必不斷地檢查假設,並簡化了代碼。具體來說,我想到了以下幾點:

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] 
相關問題