从字典中的键中获取价值

时间:2018-08-15 14:17:02

标签: python dictionary

我有一本巨大的字典,叫做Menu。这是它的摘录:

Menu= {
  'Salad': {
    'salad': {
      'PLU': '32',
      'NAME': 'salad',
    }
  },
  'Dessert': {
    'cookie': {
      'PLU': '334',
      'NAME': 'cookie ',
    }
  },
  'Appetizer': {
    'extra sauce': {
      'PLU': '61',
      'NAME': 'extra sauce',
    },
    "French Fries": {
      'PLU': '23',
      'NAME': "french fries",
    },
    'breadsticks': {
      'PLU': '59',
      'NAME': 'breadsticks',
    }

  }
}

我正在尝试通过寻找PLU来获取钥匙的价值 例如: 如果我想要“ PLU:59”。我希望出现“面包棒”和“开胃菜”。 到目前为止,我只能尝试通过手动搜索来获取数据。 那是

print(menu['Salad']['salad']['PLU'])

任何建议都会有所帮助! 请随时问我要澄清的事情。

8 个答案:

答案 0 :(得分:2)

您可以将recursion与生成器一起使用,以找到指向所需'PLU'值的键的路径:

menu = {'Salad': {'salad': {'PLU': '32', 'NAME': 'salad'}}, 'Dessert': {'cookie': {'PLU': '334', 'NAME': 'cookie '}}, 'Appetizer': {'French Fries': {'PLU': '23', 'NAME': 'french fries'}, 'breadsticks': {'PLU': '59', 'NAME': 'breadsticks'}, 'extra sauce': {'PLU': '61', 'NAME': 'extra sauce'}}}
def val_exists(d, _target):
  if isinstance(d, dict):
    return any(a == 'PLU' and b == _target if not isinstance(b, dict) else val_exists(b, _target) for a, b in d.items())

def get_values(d, target, level = 0, flag = False):
  if isinstance(d, dict):
    for a, b in d.items():
      if not level and val_exists(b, target):
        yield a
        yield from get_values(b, target, level+1, flag)
      elif a == 'PLU' and b == target:
        flag = True
      elif flag and a == 'NAME':
        yield b
      else:
        yield from get_values(b, target, level, flag)

 print(list(get_values(menu, '59')))

输出:

['Appetizer', 'breadsticks']

答案 1 :(得分:1)

如果您想在字典中使用严格的python解决方案,则可以遍历所有课程并搜索特定值

from typing import Tuple 

def search_plu(menu: dict, plu: int) -> Tuple[str, str]:
    for course, entries in menu.items():
       for entry, entities in entries.items():
           if entities['PLU'] == plu:
               return entities['NAME'], course

请注意,此解决方案使用python的type hints。如果不使用它们,则可以将其删除。

答案 2 :(得分:1)

数据结构就是一切。您最终希望拥有这个:

products['59']

给你这个:

('breaksticks', 'Appetizer')

因此,您应该对原始数据结构进行一次遍历,以创建新的数据结构,如下所示:

products = {
    '59': ('breaksticks', 'Appetizer'),
    # and so on
}

然后您将通过PLU进行有效的查找。

答案 3 :(得分:1)

来自pandas的解决方案

pd.DataFrame(Menu).stack().apply(pd.Series).loc[lambda x : x['PLU']=='59']
Out[143]: 
                              NAME PLU
breadsticks Appetizer  breadsticks  59

答案 4 :(得分:0)

def name_by_plu(menu, PLU):
    for category in menu:
        for item in menu[category]:
            if menu[category][item]['PLU'] == PLU:
                return menu[category][item]['NAME']
    return None

name_by_plu(menu, '59')

答案 5 :(得分:0)

递归遍历各个键,直到找到正确的PLU值。

def find_plu(menu, plu):
    for type in menu:
        for dish in type:
            if menu[dish][type]['PLU'] == plu:  return dish, type

通常,如果要在数据结构中搜索数据,则要遍历它。当您知道密钥的路径时,直接访问该密钥。

答案 6 :(得分:0)

这可能是解决此问题的方法,但是您可以定义一个递归函数来过滤某些键/值对的嵌套字典,并返回包含它们的字典片段。

def filter_dict(d, key, value):
    if isinstance(d, dict):
        if key in d and d[key] == value:
            return d
        else:
            return {k: fd for k, fd in ((k, filter_dict(v, key, value)) 
                                        for k, v in d.items()) if fd}

res = filter_dict(Menu, "PLU", "59")
# {'Appetizer': {'breadsticks': {'PLU': '59', 'NAME': 'breadsticks'}}}

这适用于任意嵌套的字典和任意键,并且还可以处理多个匹配项,例如,如果您将另一个PLU值更改为59,结果将是

{'Dessert': {'cookie': {'PLU': '59', 'NAME': 'cookie '}},
 'Appetizer': {'breadsticks': {'PLU': '59', 'NAME': 'breadsticks'}}}

答案 7 :(得分:0)

我将为该问题添加另一个 general 递归解决方案,该解决方案适用于您呈现的数据结构中的任意键值对。

def getBreadcrumb(node, key, value):
    if key in node:
        if node[key] == value:
            return [key]
        return []
    else:
        for other_key in node:
            result = getBreadcrumb(node[other_key], key, value)
            if result:
                result.append(other_key)
                return result
        return []

通过致电:

result = getBreadcrumb(Menu, 'PLU', '59')

您将得到以下结果:

['PLU', 'breadsticks', 'Appetizer']

变量 result 包含答案的“面包屑”(祖先和包含值59的键)。要仅获取“ PLU”的“祖先”并按照您要求的顺序显示它们,您可以执行以下操作:

result = getBreadcrumb(Menu, 'PLU', '59')[1:]
result.reverse()

哪个会给你:

['Appetizer', 'breadsticks']