简体   繁体   English

如何限制python中的递归深度?

[英]How to limit the depth of recursion in python?

I have a list of elements. 我有一个元素列表。 I want to know if there are two pairs of elements in the list, in which the elements of the pair have the same value. 我想知道列表中是否有两对元素,其中一对元素具有相同的值。

My idea is that I first compare all the elements in the list, if a pair is found, remove the pair from the list, then proceed again. 我的想法是,我首先比较列表中的所有元素,如果找到一对,则从列表中删除该对,然后再次进行。 Thus I think I can use recursion to do this task, but limit the depth to 2 to solve the problem. 因此,我认为我可以使用递归来完成此任务,但是将深度限制为2即可解决问题。

Here is my first try: 这是我的第一次尝试:

    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

I use the variable recursion_depth to record the the depth of recursion, but then realize that the return command doesn't immediately terminate the function and return true, but returns to its original caller is_twopair(card) instead. 我使用变量recursion_depth记录了递归的深度,但随后意识到return命令不会立即终止函数并返回true,而是返回其原始调用者is_twopair(card)。 So my question is: 所以我的问题是:

  1. Is there a way to immediately terminate the function and return the result true? 有没有一种方法可以立即终止函数并返回结果为true?
  2. Is there a way to limit the depth of recursion? 有没有办法限制递归的深度?

I know there maybe several ways to work around this. 我知道也许有几种方法可以解决此问题。 But I want to stay faithful to my idea and use this as an opportunity for learning. 但是我想忠实于自己的想法,并将其作为学习的机会。

I don't believe you can "break out" of the recursion without some serious black magic, nor do I believe that you should try to. 我不相信您可以在没有一些严重的黑魔法的情况下“脱离”递归,也不相信您应该尝试这样做。 Cascading the return value up the calling chain is typically a fine approach. 在返回链上级联返回值通常是一种很好的方法。

I'd personally avoid using a nonlocal variable and keep track of the recursion depth within the scope of each function call. 我个人将避免使用非局部变量,并在每个函数调用的范围内跟踪递归深度。

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

Moving the tracking of the depth into the function itself will allow the function to be called repeatedly from different locations without issue. 将深度跟踪移到函数本身中将允许从不同位置重复调用该函数而不会出现问题。

Additionally, the code can be cleaned up some using itertools.combinations . 此外,可以使用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)
yourList = [1,1,2,2,3,4]
yourDict = {}
for i in yourList:
    yourDict[i] = yourList.count(i)

This code will return the number of ocurrences for every value in the list so you can determinate the number of pairs.. 此代码将返回列表中每个值的出现次数,因此您可以确定对数。

In this case: 在这种情况下:

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

The value 1 appear 2 times, the value 2 appear 2 times, the value 3 and 4 appear 1 time. 值1出现2次,值2出现2次,值3和4出现1次。

I think the piece you're missing is a return call to pass on the results of a recursive call back up to the previous caller: 我认为您所缺少的是return调用,以将递归调用的结果传递给前一个调用者:

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

I don't really think recursion is a natural way to solve this problem, but with the above change, it should work. 我真的不认为递归是解决此问题的自然方法,但是通过上述更改,它应该可以工作。 You could avoid needing to use a nonlocal variable by passing the depth as an optional parameter. 您可以通过将depth作为可选参数传递来避免使用nonlocal变量。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM