簡體   English   中英

遞歸錯誤Python

[英]Recursion error Python

我寫了一些代碼,嘗試在列表中搜索單詞。 它不是最終版本,基本上還不能執行任何操作。 但是,我不明白代碼出了什么問題:

def findword (word, t):
    t.sort()
    midword = t[len(t)/2]
    midindex = len(t)/2
    if word > midword:
        del t[:midindex]
        findword (word, t)
    elif word < midword:
        del t[midindex+1:]
        findword (word, t)
    elif word == midword:
        return t
    else:
        return None

mydic=['apple','banana','peach','pear','melon','lemon','grape','berry']
mydic1 = findword('apple', mydic)

我遇到RuntimeError: maximum recursion depth exceeded in cmp嘗試搜索appleRuntimeError: maximum recursion depth exceeded in cmp錯誤中RuntimeError: maximum recursion depth exceeded in cmp ,當我搜索列表中的其他單詞時,它返回空列表。

請幫助我找出問題所在。 謝謝!

看一下這段代碼:

    elif word < midword:
        del t[midindex+1:]
        findword (word, t)

在您的代碼中,您將得出以下結論:該列表被簡化為僅兩個元素,即:

t == ['apple', 'banana']

在這種情況下,請看以下交互式會話:

In [15]: t = ['apple', 'banana']

In [16]: midindex = len(t)/2

In [17]: midindex
Out[17]: 1

In [18]: t[midindex+1:]
Out[18]: []

In [19]: del t[midindex+1:]

In [20]: t
Out[20]: ['apple', 'banana']

請注意,在第19行中,您什么都沒有刪除, t保持不變,然后用相同的列表調用findword並執行無限遞歸,直到堆棧空間用完。 您應該重新設計代碼以克服此問題。

我看到的另一個問題是您只是簡單地遞歸調用了findword ,但是沒有使用返回值。 代替:

    elif word < midword:
        del t[midindex+1:]
        findword (word, t)

你應該做:

    elif word < midword:
        del t[midindex+1:]
        return findword (word, t)

其他建議

  • 不要將t.sort()放在findword函數中。 排序可能很昂貴,因此您只能在findword之外執行一次。
  • 正如其他人指出的那樣,修改列表,而不是重新設計代碼,是不明智的做法
  • 如果這不是家庭作業或練習,如果您想快速查找,建議使用set
  • Python有一個稱為bisect的庫模塊,它將執行二進制搜索。

二進制搜索的實現

首先,遞歸很麻煩。 如果可以的話,請避免這樣做-不幸的話,它可能會在非常大的搜索空間中導致此類MaxRecursion錯誤。

讓我們將其切換為迭代,看看我們能做什么:

def binary_search(lst, word):
    new_lst = sorted(lst) # so we only do this once
    return _binary_search(new_lst, word, start=0, end=len(new_lst))

def _binary_search(lst, word, start, end):
    while end - start > 0: # technically this is just while end-start but...
        pivot = (start + end) // 2 # floordiv!
        pivot_element = lst[pivot]
        if word > pivot_element:
            start = pivot + 1
        elif word < pivot_element:
            end = pivot
        else: # word == pivot_element
            return word
    else: return None

>>> my_list = ['apple', 'banana', 'peach', 'pear', 'melon', 'lemon', 'grape', 'berry']
>>> print(binary_search(my_list, "strawberry"))
None
>>> print(binary_search(my_list, "pear"))
"pear"

如果您只是想在列表中搜索單詞,則可以執行以下操作:

mydic=['apple','banana','peach','pear','melon','lemon','grape','berry']

inputword = 'apple'
if inputword in mydic:
    print('yes it is in the list')
else:
    print('no it is not')

您無法在運行時更改字典。 在您的代碼中,您沒有遞歸調用返回。

def findword (word, t):
   for i in t:
      if i == word:
         return i

或者,如果您仍然喜歡使用二進制搜索:

def findword (word, t):
    t.sort()
    return findword_aux(word, t, 0, len(t)-1)

def findword_aux(word, array, first, last):
    midindex = (first + last) / 2 
    midword = array[midindex]
    if last - first == 1:
        return None
    if word == midword:
        return  midword
    elif word > midword:
        return findword_aux (word, array, midindex+1, last)
    elif word < midword:
        return findword_aux (word, array, first, midindex-1)

def run_tests():
    test1()
    test2()

def test1():
    mydic=['apple','banana','peach','pear','melon','lemon','grape','berry'] 
    result = findword('apple', mydic)
    if result == 'apple':
        print 'test1 pass'
    else:
        print 'test1 error'

def test2():
    mydic=['apple','banana','peach','pear','melon','lemon','grape','berry'] 
    result = findword('pinapple', mydic)
    if result == None:
        print 'test2 pass'
    else:
        print 'test2 error'

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM