遍历Python 3字典,递归并返回

时间:2018-06-23 20:39:09

标签: python dictionary recursion iteration

TL; DR结尾!

嗨,我在使用递归函数和字典时遇到了问题,该字典应该在找到特定键时返回一个值,但我得到的只是None。

让我们假设我正在构建一个可以在localhost:8080/MyGame/上运行的游戏,并且我有可以放在该地址末尾的HTML文件,例如localhost:8080/MyGame/Archer.html

我将使用localhost:8080/MyGame/ + Archer.html构建HTML链接,并且有一个字典,其中包含该字典的基础和每个页面的值,例如Archer.htmlKnight/Main_Castle.html,分别以archer_scknight_sc作为键(“ sc”代表次要城堡,“ mc”代表主城堡)

我制作了一个python文件来进一步表达我遇到的问题,它包含我要迭代的字典,递归函数和main方法

所以,我的字典看起来像这样:

URLS = {
    'base': 'localhost:8080/MyGame/',
    'main_castle': {
        'defenses_mc': {
            'bombard_tower_mc': 'Bombard_Tower.html',
            'fire_roaster_mc': 'Fire_Roaster.html',
            'freeze_tower_mc': 'Freeze_Tower.html'
        },
        'army_mc': {
            'troops_mc': {
                'mage_mc': 'Mage.html',
                'witch_mc': 'Witch.html',
                'knight_mc': 'Knight/Main_Castle.html',
                'berserker_mc': 'Berserker/Main_Castle.html',
            },
            'commandants': {
                'wizard_mc': 'Wizard.html',
                'warlock_mc': 'Warlock.html',
                'dragon_mc': 'Dragon.html'
            },
            'spells': {
                'upgrade_spell': 'Upgrade_Spell.html',
                'damage_spell': 'Damage_Spell.html'
            }
        },
    },
    'secondary_castle': {
        'defenses_sc': {
            'archer_tower_sc': 'Archer_Tower.html',
            'barracks': 'Barracks.html'
        },
        'army_sc': {
            'troops_sc': {
                'archer_sc': 'Archer.html',
                'knight_sc': 'Knight/Secondary_Castle.html',
                'berserker_sc': 'Berserker/Secondary_Castle.html'
            }
        }
    }
}

我的递归函数如下:

def recursion(dictionary, key_to_find):
    for key, value in dictionary.items():
        if key_to_find == key:
            print("Found! '" + key_to_find + "' value is '" + value + "'")
            return value
        elif isinstance(value, dict):
            recursion(value, key_to_find)
    return "Sorry, couldn't find anything :("

我要在以后提到的一件事:上面的代码遍历整个ENTIRE词典。

递归函数有两个参数:我要遍历的字典和要查找其值的特定键。

主要功能如下:

def main():
    knight_sc = str(recursion(URLS, 'knight_sc'))
    knight_sc_url = URLS['base'] + knight_sc
    print(knight_sc_url)

期望knight_sc等于'Knight / Second_Castle.html',因为当我运行递归函数时,它实际上会查找并打印键knight_sc的实际值,即' Knight / Second_Castle.html”,但仅返回None

这就是问题,我已经搜索过它,到处都说不能简单地在另一个函数内调用一个函数并递归地调用它,因为那可能仅仅是functionA调用functionB等等……

但是,当我在调用函数之前放上return

elif isinstance(value, dict):
    recursion(value, key_to_find) # <- return should go at the start of this line

它仅迭代到freeze_tower_mc,然后在此处停止迭代。至少在函数调用中没有return的版本会遍历整个字典,发现key等于key_to_find并打印其值,但不打印 return < / strong>该值。

例如,如果我在调用recursion()之前先调用recursion() WITH ,但是现在在我的main方法中将'fire_roaster_mc'作为参数传递,它实际上返回“ Fire_Roaster.html”,我可以使用URLS['base'] + str(recursion(URLS, 'fire_roaster_mc'))

构建HTML链接

我真的错过了一些看不见的愚蠢东西,因为经过这么多次尝试后我的头脑变得麻木了,没有任何作用,还是这是一个普遍的问题?有解决办法吗?

我还应该说我是Python的新手,来自Java,并且我只是想为乐趣而编码(从来没有做过像工作,项目或大学那样的严肃工作),到目前为止,我真的很喜欢Python,因为它简单易用:D

TL; DR:如果发现特定键,本应返回值的递归函数将返回None,但它正在查找实际键并可以打印其值

很抱歉有语法错误,因为英语不是我的母语。

谢谢!

1 个答案:

答案 0 :(得分:0)

它在freeze_tower_mc处停止,因为这是最里面的字典,而您返回Sorry, couldn't find anything是因为您已遍历该字典的所有元素。然后,将返回结果传递回调用堆栈,从而结束循环。

相反,我想,如果您想跟踪整个字典中没有找到任何内容,请传入一个depth参数,然后仅返回该循环结束并没有找到任何内容时返回的内容字典的顶部

def recursion(dictionary, key_to_find, depth=0):
    for key, value in dictionary.items():
        if key_to_find == key:
            print("Found! '{}' value is '{}'".format(key_to_find, value)) 
            return value
        elif isinstance(value, dict):
            print("Searching " + str(value) + " at depth " + str(depth+1)) 
            found = recursion(value, key_to_find, depth=depth+1)
            if found is not None:
                # if it is found, you'd see this line printed twice, once in the recursion, then once here 
                print("Found! '{}' value is '{}'".format(key_to_find, found)) 
                return found
    if depth == 0:
        return "Sorry, couldn't find anything"