【问题标题】:Loop on list causes IndexError - Python列表上的循环导致 IndexError - Python
【发布时间】:2016-11-10 19:57:05
【问题描述】:

我正在尝试使用 PYTHON 计算具有 RLE(运行长度编码)格式数字的文件的面积。我的 FOR 和 IF 语句有问题。

我正在尝试计算包含值 201 的单元格的面积。

我当前的错误:

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

这是我正在使用的文件:

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

这是我的代码:

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

【问题讨论】:

  • 哪里又定义了line
  • @kiran.koduru 好吧,我想弄清楚该放什么。我想循环遍历数组。我无法在 FOR 语句中输入哪些值。
  • 您需要逐步构建您的程序。无法粘贴一团文本并请他人为您编写。 for循环用于在python中迭代iterablesstringslisttuplesdictionaries都是可迭代对象。

标签: python arrays if-statement for-loop run-length-encoding


【解决方案1】:

这看起来是一个很大的努力。您的问题是您的索引用完了,这会引发IndexError。尽管您的情况要求每个项目都具有某种索引意识,但幸运的是您只需轮询先前迭代的值。

对于这种情况,尝试跟踪之前的值:

npixels = 0
cells = cellValuesAsIntList                         # for clarity

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

根据经验,避免改变索引迭代。虽然这不是您的直接问题,但这种做法可能会导致许多副作用。如果可能,直接迭代一个序列并处理每个迭代的项目。避免通过其他方式改变索引,例如反向迭代,改变复制的序列或使用理解。

【讨论】:

    【解决方案2】:

    假设你有:

    >>> 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)]
    

    然后您可以过滤包含一些目标值的值(即使您提到201 作为目标,我也会使用2,因为您的示例中没有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
    

    【讨论】:

    • 优雅。在 Python 3 中,您需要 &gt;&gt;&gt; list(zip(*[iter(rle)]*2))
    • 只显示结果。当然,对于最后一个循环,您可以迭代 filter...的结果...
    • 您是对的,尽管为了清楚起见,要获得您发布的结果,需要list()
    猜你喜欢
    • 1970-01-01
    • 2022-09-23
    • 2019-09-08
    • 1970-01-01
    • 1970-01-01
    • 2016-05-31
    • 1970-01-01
    • 1970-01-01
    • 2019-05-21
    相关资源
    最近更新 更多