Python Quicksort Runtime Error: Maximum Recursion Depth Exceeded in cmp

DarkPotatoKing picture DarkPotatoKing · Aug 3, 2014 · Viewed 33.1k times · Source

I'm writing a program that will read a text file containing 5,163 names. (text file can be seen here)

Then I want to store the names into a list called 'names', afterwards, I sort the list based on how many letters the name contains, shorter names are at the start of the list and the longer ones are at the end.

I used quicksort to sort the list, but when I run it, it shows this error:

C:\Python27\python.exe C:/Users/Lenovo/Desktop/Anagrams/Main.py
Traceback (most recent call last):
  File "C:/Users/Lenovo/Desktop/Anagrams/Main.py", line 25, in <module>
    names = quicksort(names)
  File "C:/Users/Lenovo/Desktop/Anagrams/Main.py", line 8, in quicksort
    greater = quicksort([x for x in list[1:] if not lessThan(x, pivot)])
  File "C:/Users/Lenovo/Desktop/Anagrams/Main.py", line 7, in quicksort
    lesser = quicksort([x for x in list[1:] if lessThan(x, pivot)])
  File "C:/Users/Lenovo/Desktop/Anagrams/Main.py", line 8, in quicksort
    greater = quicksort([x for x in list[1:] if not lessThan(x, pivot)])
  File "C:/Users/Lenovo/Desktop/Anagrams/Main.py", line 7, in quicksort
    lesser = quicksort([x for x in list[1:] if lessThan(x, pivot)])
# [.... many lines elided ...]
  File "C:/Users/Lenovo/Desktop/Anagrams/Main.py", line 8, in quicksort
    greater = quicksort([x for x in list[1:] if not lessThan(x, pivot)])
  File "C:/Users/Lenovo/Desktop/Anagrams/Main.py", line 8, in quicksort
    greater = quicksort([x for x in list[1:] if not lessThan(x, pivot)])
  File "C:/Users/Lenovo/Desktop/Anagrams/Main.py", line 7, in quicksort
    lesser = quicksort([x for x in list[1:] if lessThan(x, pivot)])
  File "C:/Users/Lenovo/Desktop/Anagrams/Main.py", line 3, in quicksort
    if list == []:
RuntimeError: maximum recursion depth exceeded in cmp

The full traceback is available as a pastie.

I've tested the quicksort function and it works for ordinary lists (ex: list = ['Alice','Bob,'Carl','Derp']), but it doesn't work if I try to sort 'names'

Here's my code

def quicksort(list):
    """Quicksort using list comprehensions"""
    if list == []:
        return []
    else:
        pivot = list[0]
        lesser = quicksort([x for x in list[1:] if lessThan(x, pivot)])
        greater = quicksort([x for x in list[1:] if not lessThan(x, pivot)])
        return lesser + [pivot] + greater

def lessThan(a, b):
    return len(a) < len(b)

#'''
input = open('Names.txt', 'r')
output = open('Names Arranged By Length.txt', 'w')

names = []

for line in input:
    line = line.translate(None, '\n')
    names.append(line)


names = quicksort(names)

for i in names:
    print i
    output.write(i)
    output.write('\n')

print 'Count: ', len(names)


input.close()
output.close()
#'''

What's wrong with my code and how do I fix it?

Answer

Martijn Pieters picture Martijn Pieters · Aug 3, 2014

You have simply hit the recursion limits. Your list of names is too large for Python's limited recursion capabilities. Your Quicksort works just fine otherwise.

You could raise the recursion limit by setting the limit higher with sys.setrecursionlimit(). You can set it a fair amount higher, but you do so at your own risk.

A better option is to use the built-in Python sort; the TimSort algorithm is far superior and won't hit a recursion limit:

names = sorted(names, key=len)

This sorts the names by their length, shortest names first.