2016-11-10 2 views
0

Я пытаюсь вычислить область файла с номерами RLE (Run Length Encoding), используя PYTHON. У меня возникают проблемы с моими заявлениями FOR и IF.Loop on list вызывает IndexError - Python

enter image description here

Я пытаюсь вычислить область ячеек, содержащих значения 201.

My current error:

Traceback (most recent call last): 
    File "D:\2016-2017\Fall2016\SpatialDataStructures\Labs\Lab4\Area_Calc_from_RLE.py", line 68, in <module> 
    if cellValuesAsIntList[i] == 201: 
IndexError: string index out of range 

Here is the file I am working with:

ncols   40 
nrows   40 
xllcorner  -2.3036649208516 
yllcorner  -1.1518324594945 
cellsize  25 
NODATA_value -9999 
13, 0, 1, 201, 26, 0, 1, 3, 12, 0, 1, 201, 39, 0, 1, 201, 39, 0, 1, 201, 39, 0, 2, 201, 33, 0, 4, 501, 2, 0, 2, 201, 32, 0, 4, 501, 3, 0, 3, 201, 29, 0, 5, 501, 5, 0, 2, 201, 26, 0, 7, 501, 6, 0, 1, 201, 25, 0, 8, 501, 6, 0, 1, 201, 25, 0, 7, 501, 7, 0, 1, 201, 25, 0, 6, 501, 8, 0, 1, 201, 25, 0, 6, 501, 8, 0, 1, 201, 6, 0, 4, 102, 15, 0, 7, 501, 7, 0, 1, 201, 6, 0, 6, 102, 14, 0, 7, 501, 5, 0, 2, 201, 6, 0, 6, 102, 15, 0, 6, 501, 5, 0, 1, 201, 7, 0, 5, 102, 16, 0, 6, 501, 5, 0, 1, 201, 7, 0, 4, 102, 18, 0, 8, 501, 2, 0, 5, 201, 3, 0, 3, 102, 19, 0, 9, 501, 5, 0, 2, 201, 25, 0, 8, 501, 6, 0, 1, 201, 29, 0, 4, 501, 6, 0, 1, 201, 29, 0, 4, 501, 6, 0, 1, 201, 9, 0, 1, 501, 5, 102, 15, 0, 2, 501, 7, 0, 1, 201, 9, 0, 6, 102, 23, 0, 2, 201, 8, 0, 1, 501, 6, 102, 3, 0, 4, 202, 15, 0, 2, 201, 4, 0, 6, 501, 6, 102, 2, 0, 2, 202, 2, 0, 8, 202, 5, 0, 4, 201, 4, 0, 8, 501, 4, 102, 3, 0, 1, 202, 5, 0, 2, 202, 3, 0, 6, 202, 1, 201, 7, 0, 8, 501, 2, 102, 1, 501, 21, 0, 1, 201, 6, 0, 11, 501, 22, 0, 1, 201, 6, 0, 8, 501, 25, 0, 1, 201, 6, 0, 8, 501, 25, 0, 1, 201, 1, 101, 5, 0, 8, 501, 25, 0, 1, 201, 1, 101, 5, 0, 8, 501, 14, 0, 3, 101, 8, 0, 1, 201, 1, 101, 5, 0, 11, 501, 12, 0, 4, 101, 6, 0, 2, 201, 1, 101, 4, 0, 12, 501, 11, 0, 4, 101, 6, 0, 1, 101, 1, 201, 1, 101, 4, 0, 12, 501, 21, 0, 1, 101, 1, 201, 5, 0, 11, 501, 23, 0, 1, 201, 5, 0, 8, 501, 26, 0, 1, 201, 5, 0, 8, 501, 26, 0, 1, 201, 5, 0, 7, 501, 27, 0, 1, 201, 5, 0, 8, 501, 8, 0 

This is my code:

fi = open(r'D:\2016-2017\Fall2016\SpatialDataStructures\Labs\Lab4\Data\AsRLE.txt','r') 
fileLines = fi.readlines() 
fi.close 
#--------------------------------------------------------------------- 

#--------------------------------------------------------------------- 
#Populated variables required for code from fileLines variable 
cellValuesAsString = [] 
lineNum = 0 
for line in fileLines: # for each line the FileLines List 
    # get number of cols, ncols, i.e. the 1st line in the file 
    if lineNum == 0: 
    ncols = int(line[14:]) 
    # get number of rows, nrows, i.e. the 2nd line in the file 
    elif lineNum == 1: 
    nrows = int(line[14:]) 
    # get cell size, cellsize, i.e. the 5th line in the file 
    elif lineNum == 4: 
    cellsize = int(line[14:]) 
    # get cell values in RLE format as String, , i.e. the 7th line in the file 
    elif lineNum == 6: 
    cellValuesAsString = line 
    lineNum = lineNum + 1 

# removes spaces 
cellValuesAsString = cellValuesAsString.replace(" ", "") 

# convert string into a list of strings split by comma 
cellValuesAsStringList = cellValuesAsString.split(',') 

# convert strings to integers 
cellValuesAsIntList = cellValuesAsStringList 
for index, item in enumerate(cellValuesAsStringList): 
    cellValuesAsIntList[index] = int(cellValuesAsStringList[index]) 
#--------------------------------------------------------------------- 

#THIS IS WHERE YOU WRITE YOUR CODE 

#--------------------------------------------------------------------- 
cellCode = 201 
codeArea = 0 

area = 0 
npixels = 0 
i = 1 

for cellValuesAsIntList in line: 
    if cellValuesAsIntList[i] == 201: 
    b = cellValuesAsIntList[i-1] 
    npixels = npixels + b 
    else: 
    i=i+2 




print npixles 
print "Area: " + npixels * cellSize 
+1

Где 'line' определено снова? –

+0

@ kiran.koduru Ну, я пытаюсь выяснить, что туда положить. Я хочу перебрать массив. У меня возникли проблемы с значениями, которые нужно ввести в оператор FOR. – Tristan

+0

Вам необходимо создать свою программу шаг за шагом. Нельзя вставить кусок текста и попросить кого-нибудь написать его для вас. Цикл 'for' используется для итерации через' iterables' в python 'strings',' list', 'tuples',' словари' - все итерации. –

ответ

0

Это выглядит как большое усилие. Ваша проблема в том, что у вас заканчиваются индексы, что повышает уровень IndexError. Хотя ваша ситуация требует, чтобы каждый элемент был осведомлен об индексе, к счастью, вам нужно только опросить ранее измененную ценность.

Для таких ситуаций, попробуйте отслеживать предыдущее значение:

npixels = 0 
cells = cellValuesAsIntList       # for clarity 

prev = None 
for cell in cells: 
    if cell == 201: 
     npixels += prev        # increment operator 
    prev = cell 

Как правило, остерегайтесь мутирует индексы и итерация. Хотя это не ваша прямая проблема, эта практика может вызвать множество побочных эффектов. Если возможно, прямо итетерируйте последовательность и работайте с каждым итерированным элементом. Избегайте изменения индексов другими способами, например. обратная итерация, мутация скопированной последовательности или использование понятий.

0

Предположим, у вас есть:

>>> rle=[2,5,1,8,6,9,3,30,6,22,2,12] 

Вы можете превратить это в длину перспективе кортежей так:

>>> zip(*[iter(rle)]*2) 
[(2, 5), (1, 8), (6, 9), (3, 30), (6, 22), (2, 12)] 

Тогда можно отфильтровать значения, содержащие некоторое целевое значение (я буду использовать 2 даже хотя вы указываете 201 как цель, потому что ваш пример не содержит 201):

>>> filter(lambda t: t[0]==2, zip(*[iter(rle)]*2)) 
[(2, 5), (2, 12)] 

Затем применить это к файлу:

with open(file_name) as f_in: 
    for line in f_in: 
     li_as_ints=map(int, line.split(",")) 
     fl=filter(lambda t: t[0]==201, zip(*[iter(li_as_ints)]*2)) 
     # produces all the values, expanded, with 121 as value... 

Пожалуйста не сделать что-то вдоль этих линий:

fh=open(a_file_name) 
lines=fh.readlines() 
for line in lines: 
    #process a line 

Вы излишне чтение всего файла.

Вместо делать:

with open(a_file_name) as f_in: 
    for line in f_in: 
    # process a line 
+0

Элегантный. В Python 3 вам понадобится '>>> list (zip (* [iter (rle)] * 2))'. – pylang

+0

Кликните здесь, чтобы показать результаты. Для конечного цикла, конечно, вы можете просто перебирать результат 'filter' ... – dawg

+0

Вы правы, хотя для ясности, чтобы получить отправленный вами результат, вам понадобится« list() ». – pylang