简体   繁体   中英

How to fix 'IndexError: list index out of range' error

I am a beginner and took python and introductory algorithms and was trying to implement what I was learned. I was trying the following code but it was repeatedly giving me 'IndexError: list index out of range.' It fails at partition function, specifically at array[0],array[pivot]=array[pivot],array[0] code. I couldn't be able to fix it. Any help is appreciated.

from math import floor

def mergeSort(a):           # mergesort function
    if len(a)<2:            # if length of a < 2, return a
        return a
    mid=int(len(a)/2)       # mid point
    x=mergeSort(a[:mid])    # recursivly call mergesort for 0 to mid
    y=mergeSort(a[mid:])    # recursivly call mergesort from mid to end
    result=[]               # empty list
    i=j=0                   # initialize i and j
    while j<len(x) and i<len(y):          
        if x[j]<y[i]:          # if x[j] < y[i], then append result for x[j]
            result.append(x[j])
            j+=1               # increment j by 1
        else:
            result.append(y[i])   # append result for y[i]
            i+=1               # increament i by 1
    result+=x[j:]              # add x[j:] --> result
    result+=y[i:]              # add y[i:] --> result
    return result              # return the result

def findMedian(a):               # find the median
    return mergeSort(a)[floor(len(a)/2)]   # call mergesort

def choosePivot(a):               # choose pivot
  medians=[]                      # empty list
  j=0                             # initialize j
  if len(a)==1:                   # if the len = 1, print the element
      print (a[0])
      return a[0]
  if 5<len(a):                    
      medians.append(findMedian(a[0:5]))      # call findMedian for 0 to 5
  else:
      medians.append(findMedian(a))           # call findMedian for a
  for i in range(1,floor(len(a)/5)):         # divide the input array into 5 groups 
      if i*5<len(a):
          medians.append(findMedian(a[j*5:i*5]))   # call findMedian
      else:
          medians.append(findMedian(a[j*5:len(a)]))
  return choosePivot(medians)        # return choosePivot medians

def partition(array,pivot):        # partition
    array[0],array[pivot]=array[pivot],array[0]   #swap
    j=1                  # intiatalize 

    for i in range(1,len(array)): 
        if array[i]<array[0]:
            array[i],array[j-1]=array[j-1],array[i]   #Swap the number less than the pivot
            j+=1

    array[1],array[j]=array[j],array[1]   #swap the pivot to its rightful place
    return j-1,array     #return index of pivot and the partitioned array

def Selection(array,k):         # selection function
    p=choosePivot(array)      

    if k>len(array):        # if k > length of array, then return -1
        print ("Out of array index")
        return -1

    if len(array)>1:             # if len(array) >1, then
        x,b=partition(array,p)           # call partition func
        if x>k:
            c = Selection(b[:x],k)       # search the left half for the statistic
            return c                     # return c
        elif x<k:
            d= Selection(b[x+1:],k-x-1)   # search the right half for the statistic
            return d                      # return d
        else:
            return array[k]               # return the element if statistic is found

    else:
        return array[0]   #Only one element. Only solution, return as it is.
print (Selection([5,1,48,6,2,4,8,7,5,63,2,1,4,8,99],13))

How to fix "index out of range" errors? Debugging. Great read: How to debug small programs (#1) . Use print statements or better a debugger to stop at certain positions in your code and inspect whats going wrong. I use Visual Studio for that.

The red dot is a breakpoint - whenever the code hits the red dot it stops execution and I can inspect things to my hearts content. I can then advance line-wise. The yellow arrow shows in which line I am.

VS can pin variables as overlay to your sourcecode - see the small pieces to the right of the image.

List of debugging tools: https://wiki.python.org/moin/PythonDebuggingTools


When putting your program through VS the 3rd time it hits def partition(array,pivot): it is out of bounds:

值而不是索引

Reason being that your pivot contains the value not the index that you need to swap it.

Even if you fix it to:

def partition(array,pivot):        # partition
    idx = array.index(pivot) # get the index of the value here
    array[0],array[idx]=array[idx],array[0]   #swap
    j=1                  # intiatalize 

    for i in range(1,len(array)): 
        if array[i]<array[0]:
            array[i],array[j-1]=array[j-1],array[i]   #Swap the number less than the pivot
            j+=1

    array[1],array[j]=array[j],array[1]   #swap the pivot to its rightful place
    return j-1,array     #return index of pivot and the partitioned array

You run into another error when swapping array[1],array[j]=array[j],array[1] due to j being too large:

j太大

You need to fix your algorithms.

HTH

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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