如何从嵌套字典中按值获取字典键?

时间:2020-10-20 14:35:55

标签: python function dictionary key key-value

我有字典

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)]

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

3 个答案:

答案 0 :(得分:1)

您将返回每个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变量),因为这不是一个好习惯。

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

答案 1 :(得分: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)) == []

答案 2 :(得分:0)

也许您的整个结构是错误的。那怎么办?

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': '#'}