[英]Why maximum recursion depth exceeded is not (always) happening in python list comprehension?
[英]Maximum recursion depth error, somehow related to list comprehension notation
我是Python的新手,我對以下內容感到困惑。
作為速成課程的一部分,我使用列表quicksort
編寫了一個quicksort
函數,如下所示:
data = [78,3,3526,-12244,9,2,8,6,-84,3642,1,-1234, 234, 23, -1, -11, 34]
pivot = data[0]
def quicksort(lst):
if len(lst) <= 1:
return lst
lessThanPivot = [x for x in lst if x < pivot]
greaterThanPivot = [x for x in lst if x >= pivot]
return quicksort(lessThanPivot) + [pivot] + quicksort(greaterThanPivot)
print(quicksort(data))
這導致以下輸出:
Traceback (most recent call last):
File "C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE\Extensions\Microsoft\Python Tools for Visual Studio\2.1\visualstudio_py_util.py", line 106, in exec_file
exec_code(code, file, global_variables)
File "C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE\Extensions\Microsoft\Python Tools for Visual Studio\2.1\visualstudio_py_util.py", line 82, in exec_code
exec(code_obj, global_variables)
File "C:\Users\user\documents\visual studio 2013\Projects\PythonApplication1\PythonApplication1\quickSortExercise.py", line 12, in <module>
print(quicksort(data))
[...]
File "C:\Users\user\documents\visual studio 2013\Projects\PythonApplication1\PythonApplication1\quickSortExercise.py", line 3, in quicksort
def quicksort(lst):
RuntimeError: maximum recursion depth exceeded
但以下工作正常:
data = [78,3,3526,-12244,9,2,8,6,-84,3642,1,-1234, 234, 23, -1, -11, 34]
pivot = data[0]
def quicksort(lst):
if len(lst) <= 1:
return lst
lessThanPivot = [x for x in lst[1:] if x < pivot]
greaterThanPivot = [x for x in lst[1:] if x >= pivot]
return quicksort(lessThanPivot) + [pivot] + quicksort(greaterThanPivot)
print(quicksort(data))
唯一的區別是lst[1:]
而不是lst
關於列表推導的文檔似乎沒有解決這個問題。
您永遠不會在第一個片段中更改您的數據透視圖,因此lessThanPivot
的“less-than”分區再次是lessThanPivot
(即等效列表),而greaterThanPivot
的“大於”分區再次是greaterThanPivot
,導致無限遞歸。
你的第二個片段“有效”,因為lst[1:]
不斷修剪列表的第一個元素,因此每次重復時列表會變小,最終導致基本情況。 然而,最終答案是不正確的。
簡而言之,在每個分區之前選擇一個新的樞軸。
somelist[1:]
使用切片表示法生成一個列表,其中包含第一個之后的所有元素。 有關切片表示法的解釋,請參閱此問題 。
第一次排序失敗的原因是因為列表greaterThanPivot
將始終也包含pivot,因為pivot是第一個元素,並且使用的條件是x >= pivot
。 因此, greaterThanPivot
上的遞歸始終包含相同的pivot,並且在第一個分區之后永遠不會變小。 在您的示例中,在第一步之后, greaterThanPivot = [78, 3526, 3642, 234]
,如果您通過算法跟蹤這一點,您將看到它將始終包含此值,直到您用完堆棧空間。
在第二種算法中,切片表示法用於刪除列表的第一個元素,也就是說,它在分區之前刪除了數據透視表。 這可以防止包含數據透視表的列表上的無限遞歸。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.