#python #function #dictionary #key #key-value
#python #функция #словарь #Клавиша #ключ-значение
Вопрос:
У меня есть словарь
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)]
итак, как я могу улучшить свой код? Я знаю, что этот код ужасен, но я только учусь
Ответ №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)) == []
Комментарии:
1. почти, но мне не нужна операция «импорт». Я хотел бы написать правила, но я не могу 🙂 поэтому мне нужно написать код без импорта
2. @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
ключа O (1), итерация по нему для получения значения равна O (n) . Кроме того, я бы не стал использовать глобальную переменную (ваша функция использует game_objects
переменную, даже если она не получает ее в качестве аргумента), поскольку это не очень хорошая практика.
Надеюсь, это помогло! Удачи и счастливого кодирования!
Комментарии:
1. Это хороший совет, я прочитаю о методе 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': '#'}
Комментарии:
1. Не могу изменить структуру словаря, это было по умолчанию