web-dev-qa-db-ja.com

Pythonクイックソートランタイムエラー:cmpで最大再帰深度を超えました

5,163個の名前を含むテキストファイルを読み取るプログラムを作成しています。 (テキストファイルを見ることができます ここ

次に、名前を「names」というリストに保存します。その後、名前に含まれる文字数に基づいてリストをソートします。短い名前はリストの先頭にあり、長い名前はリストの最後にあります。

クイックソートを使用してリストを並べ替えましたが、実行すると次のエラーが表示されます。

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

完全なトレースバックが利用可能です パスティーとして

クイックソート機能をテストし、通常のリスト(例:list = ['Alice'、 'Bob、' Carl '、' Derp '])で機能しますが、' names 'をソートしようとしても機能しません

これが私のコードです

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()
#'''

私のコードの何が問題になっていますか、どうすれば修正できますか?

15
DarkPotatoKing

単に再帰の制限に達しました。名前のリストが大きすぎて、Pythonの限定的な再帰機能を使用できません。それ以外の場合、Quicksortは正常に機能します。

あなたはcouldsys.setrecursionlimit() で制限を高く設定することで再帰制限を上げます。それをかなり高く設定することもできますが、自分の責任で行ってください。

より良いオプションは、組み込みのPython sort; TimSortアルゴリズム がはるかに優れており、再帰制限に達しないことです。

names = sorted(names, key=len)

これにより、名前が長さでソートされ、最短の名前が最初になります。

17
Martijn Pieters

超過するpythonデフォルトの再帰サイズ。デフォルトの再帰制限は1000です。再帰制限を増やすことはできますが、推奨されません。

import sys
sys.setrecursionlimit(1500)

提案
私の提案は、 numpy.argsort() メソッドを使用することです。これは、多くのソートアルゴリズム用にすでに準備されています。 これは簡単な例です numpyライブラリを使用してクイックソートアルゴリズムを実行する方法について。

6
Harun ERGUL