2017-02-16 66 views
0

我有一個元素列表。我想知道列表中是否有兩對元素,其中元素對的元素具有相同的值。如何限制python中的遞歸深度?

我的想法是,我首先比較列表中的所有元素,如果找到一對,則從列表中刪除該對,然後再繼續。因此我認爲我可以使用遞歸來完成這個任務,但是將深度限制爲2來解決問題。

這是我第一次嘗試:

recursion_depth=0 
     def is_twopair(card): 
      nonlocal recursion_depth 
      if recursion_depth==2: return True 
      for i in range(0, len(card)): 
       for k in range(i+1,len(card)): 
        if card[i].value==card[k].value: 
         del card[k], card[i] 
         recursion_depth+=1 
         is_twopair(card)  
        else: continue 
       else: continue 
      else: return False 

我使用變量recursion_depth記錄遞歸的深度,但後來意識到,返回的命令不會立即終止函數並返回true,但回報而不是原來的調用者is_twopair(卡)。所以我的問題是:

  1. 有沒有辦法立即終止函數並返回結果true?
  2. 有沒有辦法限制遞歸的深度?

我知道可能有幾種方法來解決這個問題。但我想保持忠實於我的想法,並將其作爲學習的機會。

+1

你能複製一個你的列表的例子嗎? – Ika8

+0

我的清單是一張撲克類卡片的對象清單。例如:[TD,TH,KD,KH,QD]。 (TD代表十顆鑽石,TD代表十顆心,KD代表King Diamond等)。屬性值表示卡的13個可能值之一(2,3,4 ... 10,J,Q,K A)。但我認爲這與問題無關。問題可以在任何類型的任何列表中鑄造。上面的列表應該返回true(我們有2張牌,2張國王牌) –

回答

0

我認爲你缺少一塊是return調用一個遞歸調用的結果傳回了以前的來電者:

if card[i].value==card[k].value: 
    del card[k], card[i] 
    recursion_depth+=1 
    return is_twopair(card)  # add return here! 

我真的不認爲遞歸是一種自然的方式要解決這個問題,但是隨着上述變化,它應該起作用。您可以通過將depth作爲可選參數來避免需要使用nonlocal變量。

+0

我使用遞歸,因爲我剛學過它並想以某種方式應用它。 ;) –

0
yourList = [1,1,2,2,3,4] 
yourDict = {} 
for i in yourList: 
    yourDict[i] = yourList.count(i) 

此代碼將返回列表中ocurrences的數量爲每一個值,因此您可以確定的對數..

在這種情況下:

yourDict - - > { 1:2,2:2,3:1,4:1}

值1出現2次,值2出現2次,值3和4出現1次。

+0

我不確定這是OP的含義。 但是,這裏有一個更短的方式做你做了什麼: '從收藏導入Counter' '數=計數器(yourList)' –

+0

編輯我的回答,我接受你的解決方案 – Ika8

+0

這是一個很好的辦法做到我的任務。感謝你的回答 !我想知道我的方式是否可能。 –

1

我不相信你可以在沒有一些嚴重的黑魔法的情況下「突破」遞歸,也不相信你應該嘗試。將返回值級聯到調用鏈上通常是一種很好的方法。

我個人避免使用非局部變量並在每個函數調用的範圍內跟蹤遞歸深度。

def remove_pairs(card, count=2, depth=0): 
    if depth == count: 
     return card 

    for i in range(0, len(card)): 
     for j in range(i+1, len(card)): 
      if card[i].value == card[j].value: 
       del card[j], card[i] 
       return remove_pairs(card, count, depth+1) # add return here 

將深度的跟蹤移動到函數本身將允許從不同位置重複調用該函數而不會出現問題。

此外,代碼可以使用itertools.combinations清理一些。

from itertools import combinations 

def remove_pairs(cards, count=2, depth=0): 
    if depth == count: 
     return cards 

    for card1, card2 in combinations(cards, 2): 
     if card1.value == card2.value: 
      cards.remove(card1) 
      cards.remove(card2) 
      return remove_pairs(cards, count, depth+1) 
+0

這是我如何跟蹤深度,如果試圖分析性能問題。瞭解sys.setrecursionlimit()也很好,但如果你明確知道你需要一些比默認值稍大的有限值(例如對於某些動態編程算法),那麼增加它就更好了。 –

+0

我不喜歡如何在任意深度中止遞歸,但無論如何返回一個值。這應該是某種例外。 –

+0

@KennyOstrom問題具體要求遞歸在2的深度中止。 –