indexError:列表索引超出范围

时间:2016-06-25 08:05:03

标签: python

该程序用于快速排序,具有重复键。代码运行一次或两次,然后下次给出IndexError,尽管列表不为空。当我打印索引时,它们位于范围内。这是我的一个问题特别是计算机?

编辑添加了追溯

import random


def partition(n,lo,hi):
    i=lo
    lt=lo    #index showing the start of all duplicate partitioning keys
    gt=hi    #index showing the end of all duplicate partitioning keys
    x=n[lt]

    while(i<=gt):
        while(n[i]<=n[lt] and i<=gt):
            if(x!=n[lt]):
                print("alert!!!")
            if(n[i]<n[lt]): #current alement not a duplicate of partitioning alement
                if(lt<=i):
                    n[lt],n[i]=n[i],n[lt]
                    #print(n)
                i+=1
                lt+=1
            else: #current element is a duplicate partitioning alement
                #print(n[i],"=",n[lt])
                i+=1

        while(n[gt]>n[lt] and i<=gt):
            gt-=1

        if(i<gt):
            n[i],n[gt]=n[gt],n[i]
            gt-=1
            #print(n)


    return gt



def quickSort(n,lo,hi):
    #print("called")
    if(lo<hi):
        print(n)
        p=partition(n, lo, hi)
        quickSort(n, lo, p-1)
        quickSort(n, p+1, hi)

def main():
    nums=[]
    for i in range(30):
        nums.append(random.randrange(100))
    print("original array")
    print(nums)
    k=4
    hi=len(nums)-1
    #print(k,"th lowest number is ",quickSelect(nums, 0,hi,k))
    print(nums)
    quickSort(nums,0,hi)
    print(nums)

if __name__ == "__main__":
    main()  

回溯:

Traceback (most recent call last):
  File "C:\Users\S.reddy\workspace\sorter\src\selector\quickSelect.py", line 59, in <module>
    main()   
  File "C:\Users\S.reddy\workspace\sorter\src\selector\quickSelect.py", line 55, in main
    quickSort(nums,0,hi)
  File "C:\Users\S.reddy\workspace\sorter\src\selector\quickSelect.py", line 43, in quickSort
    quickSort(n, p+1, hi)
  File "C:\Users\S.reddy\workspace\sorter\src\selector\quickSelect.py", line 41, in quickSort
    p=partition(n, lo, hi)
  File "C:\Users\S.reddy\workspace\sorter\src\selector\quickSelect.py", line 11, in partition
    while(n[i]<=n[lt] and i<=gt):
IndexError: list index out of range

2 个答案:

答案 0 :(得分:0)

问题出在第11行:

    while(n[i]<=n[lt] and i<=gt):

您需要将其更改为:

    while(i<=gt and n[i]<=n[lt]):

因为python首先检查第一个条件(在这种情况下它是i&lt; = gt)并且如果它是真的而不是他检查第二个(n [i]&lt; = n [lt])但是如果第一个条件是false然后python退出while循环而不检查第二个条件。

答案 1 :(得分:0)

由于您在内部while循环中检查条件的顺序,您的代码有时会超出边界索引。

通常,调试此类问题的最简单方法是在代码中添加tryexcept块,except块打印出有用的诊断值。我在你的循环中使用了这个变体来找出问题:

try:
    while(n[i]<=n[lt] and i<=gt):
        if(x!=n[lt]):
            print("alert!!!")
        if(n[i]<n[lt]): #current alement not a duplicate of partitioning alement
            if(lt<=i):
                n[lt],n[i]=n[i],n[lt]
                #print(n)
            i+=1
            lt+=1
        else: #current element is a duplicate partitioning alement
            #print(n[i],"=",n[lt])
            i+=1
except IndexError:
    print(i, gt, len(n))
    raise

您会发现,在某些情况下,gt将为len(n) - 1i将为len(n)。在这种情况下,while(n[i]<=n[lt] and i<=gt):中的第一个测试会引发IndexError,因为n[i]不是有效索引。

相反,您应该首先使用i <= gt以其他顺序放置测试。如果该测试为False,则and将“短路”并且不评估第二个测试,这将导致异常。所以:使用while i <= gt and n[i] <= n[lt]:(括号是不必要的,所以我删除它们并将术语与运算符间隔开。有关Python样式的更多建议,请参阅PEP 8。)