【问题标题】:Get deeply nested key value without for loop in Python在 Python 中无需 for 循环即可获得深度嵌套的键值
【发布时间】:2017-01-09 17:03:31
【问题描述】:

我没有使用 Python 的经验,我正在尝试直接从嵌套字典中查询键值。我正在处理以下内容:

"Items": {
  "Ingredients": {
    "M": {
      "sugar": {
        "S": "three quarters of a cup"

我可以通过使用for loop 获得我需要的东西,但是如果我知道密钥被命名为sugar 我怎么能直接.get() 呢?当您已经知道自己想要什么时,使用for loop 似乎是一种浪费循环。

编辑:我正在查询 DynamoDB 表,我得到的响应是 dict 形式。我的搜索查询是 results=client.query(**allmyargs),所以如果我没记错的话,我的 dict 名称就是 results。

当我尝试results['Items']['Ingredients']['M']['sugar'] 时,我收到list indices must be integers, not str 的错误。

最终编辑:我还有很多东西要学。

【问题讨论】:

  • obj['Items']['Ingredients']['M']['sugar'] ?
  • 直接访问密钥? data['Items']['Ingredients']['M']['sugar']。你会用循环做什么?
  • OP,这就是字典的全部意义; 如果你知道密钥,你就可以得到值。没有循环,什么都没有。
  • objdata 代表什么?我正在使用循环,因为我足够新,以至于我不知道如何直接访问密钥。 :\
  • 呃,它们代表你刚刚发布的对象。

标签: python json dictionary


【解决方案1】:

您的实际响应对象的结构与您发布的示例不同,这意味着无法提供访问数据的准确方法。

JSON 和嵌套列表+字典很难阅读。一种方法是复制/粘贴到 jsonlint.com 并“验证”。尽管这对于 python 对象会失败,但它更容易阅读。我发现这比漂亮的打印更快,但这也是一种选择。

根据您在 cmets 中的说明:

results = {u'Count': 1, u'Items': [{
        u'Ingredients': {
            u'M': {
                u'MacIntosh apples': {
                    u'S': u'six cups'
                },
                u'flour': {
                    u'S': u'two tablespoons'
                },
                u'sugar': {
                    u'S': u'three quarters of a cup'
                },
                u'lemon juice': {
                    u'S': u'one tablespoon'
                },
                u'nutmeg': {
                    u'S': u'one eighth of a teaspoon'
                },
                u'cinnamon': {
                    u'S': u'three quarters of a teaspoon'
                },
                u'salt': {
                    u'S': u'one quarter of a teaspoon'
                }
            }
        }
    }], u'ScannedCount': 1
}

# First get one of the inner dictionaries
ingredients = results['Items'][0]['Ingredients']['M']

# List of ingredients you are looking for
ingredients_wanted = ['sugar', 'flour', 'nutmeg', 'salt']

# Convert list to a set for faster lookups (not absolutely necessary, especially for small lists)
ingredients_wanted = set(ingredients_wanted)

amount_list = []
for ingredient, amount in ingredients.items():
    if ingredient in ingredients_wanted:
        print('Ingredient: {} \t in amount: {}'.format(ingredient, amount['S']))

print('\n')                
# Or directly without iterating the whole thing
for item in ingredients_wanted:
    amount = ingredients[item]['S']
    print('Ingredient: {} \t in amount: {}'.format(item, amount))

【讨论】:

  • 先生f in WIZARD!谢谢一百万,伙计。我在这里没有足够的信誉来充分感谢您的指导和帮助。这就像一个魅力。非常感谢!
  • @AppleBaggins 不客气。如果答案解决了您的问题,那么感谢某人的堆栈溢出方式是accept it as the answer,即使您无法对答案进行投票,您也可以这样做:) 这也为您提供了一些声誉和信号给其他人而不是问题现已解决。
  • 完成!感谢您使我的第一篇文章富有成果和教育意义!
  • @AppleBaggins 不用担心。你会看到很多时候人们评论要求“M.C.V.E.”对于模棱两可的问题。您可以找到有关该here 的详细信息。这将提供有关人们正在寻找的东西的提示,例如在这种情况下,准确的数据结构(就像您评论中的那个。如果它是一个巨大的响应,只是一个代表性的部分)和您尝试的一些代码并没有解决问题,例如您想避免的 for 循环。这将有助于下次拒绝投票:)
  • 考虑通知我!希望下一次,我对 Python 有足够的了解,可以准确地展示我正在做的事情。 :)
【解决方案2】:
import requests
import json 
r ="""{
"Items": {
  "Ingredients": {
    "M": {
      "sugar": {
        "S": "three quarters of a cup"
}}}}}"""
j = json.loads(r)


print j['Items']['Ingredients']["M"]["sugar"]

输出

 {u'S': u'three quarters of a cup'}

【讨论】:

  • 谢谢!有没有办法在不导入更多模块或库的情况下做到这一点?
  • 你需要使用for循环或库
猜你喜欢
  • 2012-12-01
  • 2021-03-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-09
  • 1970-01-01
  • 2012-06-27
  • 1970-01-01
相关资源
最近更新 更多