【问题标题】:How to get a dictionary key by value from a nested dictionary?如何从嵌套字典中按值获取字典键?
【发布时间】:2020-10-20 14:35:55
【问题描述】:

我有一本字典

game_objects = {
    ('wall', 0): {'position': (0, 0), 'passable': False, 'interactable': False, 'char': '#'},
    ('wall', 1): {'position': (0, 1), 'passable': False, 'interactable': False, 'char': '#'},
    ('player',): {'position': (1, 1), 'passable': True, 'interactable': True, 'char': '@', 'coins': 0},
    ('soft_wall', 11): {'position': (1, 4), 'passable': False, 'interactable': True, 'char': '%'}
}

我需要创建一个函数,该函数将从嵌套字典中按值获取字典键。例如:

get_objects_by_coords((0, 1)) == [('wall', 1)]
get_objects_by_coords((1, 1)) == [('player',)]
get_objects_by_coords((2, 1)) == []

这是我所做的:

def get_objects_by_coords(position):
    for position in game_objects.values():
        if position in game_objects.values():
            return game_objects.keys()


print(get_objects_by_coords((0, 0)))

但答案不正确

dict_keys([('wall', 0), ('wall', 1), ('player',), ('soft_wall', 11)])

我只需要这部分

[('wall', 1)]

那么,我该如何改进我的代码?我知道这段代码很糟糕,但我只是在学习

【问题讨论】:

    标签: python function dictionary key key-value


    【解决方案1】:

    这是你的意思吗?

    def get_objects_by_coords(position):
        return [key for key, val in game_objects.items()
                    for k, v in val.items() if k == 'position' and v == position]
    
    assert get_objects_by_coords((0, 1)) == [('wall', 1)]
    assert get_objects_by_coords((1, 1)) == [('player',)]
    assert get_objects_by_coords((2, 1)) == []
    

    【讨论】:

    • 几乎,但我不需要“导入”操作。我希望我能写规则,但我不能:) 所以我需要写一个没有导入的代码
    • @Ruslan - 这些导入只是类型提示。您可以忽略它们并删除它们的所有外观 - 这对代码无关紧要,至少对您的目的而言不是。为了您的方便,我编辑了答案。
    【解决方案2】:

    您返回的是每个 dict 密钥,而不是您找到的密钥。我建议您查看dict.items 方法,该方法返回一对键值。因此,您的函数可能如下所示:

    def get_objects_by_coords(game_objects, position):
        for key, value in game_objects.items():
            if position == value.get('position', (None,)):
                return key
    get_objects_by_coords(game_objects, (0, 1)) # == ('wall', 1)
    

    另外,如果您要在程序中对字典进行多次迭代,我不会像您那样使用数据结构,因为尽管查看 dict 键 i O(1),但迭代它得到一个值是 O(n)。此外,我不会使用全局变量(您的函数使用 game_objects 变量,即使它没有将其作为参数接收),因为这不是一个好习惯。

    希望这有帮助!祝你好运,编码愉快!

    【讨论】:

    • 这是一个很好的建议,我将阅读有关 items 方法的信息,但代码在我获得此任务的站点上失败。您的代码是正确的,但网站上的程序说这不是答案。但我想我可以解决它。谢谢
    【解决方案3】:

    也许你的整个结构是错误的。这个呢?

    game_objects =  [
        [
            {
                'type':'wall',
                'item_no':0,
                'passsable':False,
                'interacable':False,
                'char':'#'
            },
            
            {
                'type':'wall',
                'item_no':1,
                'passsable':False,
                'interacable':False,
                'char':'#'
            }
        ],
        [
            {
                'type':'player',
                'item_no':None,
                'passable':True,
                'interactable': True,
                'char': '@',
                'coins': 0
            },
            {
                'type':None
            },
            {
                'type':None
            },
            {
                'type':None
            },
            {
                'type':'soft_wall',
                'item_no': 11,
                'passable': False,
                'interactable': True,
                'char': '%'}
        ],
        
    ]
    

    输出

    game_objects[1][4]
    
    {'type': 'soft_wall',
     'item_no': 11,
     'passable': False,
     'interactable': True,
     'char': '%'}
    
    game_objects[0][1]
    
    {'type': 'wall',
     'item_no': 1,
     'passsable': False,
     'interacable': False,
     'char': '#'}
    

    【讨论】:

    • 不能改变字典的结构,它是默认的
    猜你喜欢
    • 1970-01-01
    • 2014-12-06
    • 2019-12-04
    • 1970-01-01
    • 2021-05-10
    • 1970-01-01
    • 1970-01-01
    • 2013-02-19
    • 2012-05-21
    相关资源
    最近更新 更多