【问题标题】:Testing nested dictionaries for a user input and retrieving directly related information测试用户输入的嵌套字典并检索直接相关的信息
【发布时间】:2018-11-12 14:35:55
【问题描述】:

我是 Python 3 的新手,一直在尝试使用字典,但在测试特定键和从嵌套字典中检索其相关值时遇到问题。

我希望根据嵌套字典检查用户定义的输入,如果找到用户输入,我想收集该项目的详细信息并将其添加到另一个字典。

例如

basketDict = {}
shopDict = {"Fruit": {"Apple": "2", "Banana": "3"},
             "Vegetables": {"Lettuce": "5", "Potato": "7"}}
userQuery = input("What food do you want to check for? ")

userQuery = "苹果"

想要的结果:

basketDict = {"Fruit": {"Apple": "2"}}

我尝试使用字典理解来形成仅包含食品(苹果、香蕉、生菜等)的新字典,但在尝试收集相关类别(“水果”/“蔬菜”和来自嵌套字典的数量信息。

这是我的(损坏的)代码:

basketDict = {}
shopDict = {"Fruit": {"Apple": "2", "Banana": "3"},
             "Vegetables": {"Lettuce": "5", "Potato": "7"}}
shopCheck = []

userQuery = input("What food do you want to check for? ")
for category, food in shopDict.items():
    for each in food:
        shopCheck.append(each)

    if userQuery not in shopCheck:
        print("That's not available.")
    else:
        print(userQuery + " added to basket. ")
        basketDict[category] = [food]

print(basketDict)

【问题讨论】:

    标签: python python-3.x dictionary nested dictionary-comprehension


    【解决方案1】:

    此代码足以满足您的要求:

    for category, food in shopDict.items():
        if userQuery in food:
            basketDict[category] = {userQuery: food[userQuery]}
    

    但如果你想在购物篮中添加新商品,你应该正确更新它:

    for category, food in shopDict.items():
        if userQuery in food:
            basketDict.update(
                {category: {**basketDict.get(category, {}),
                            **{userQuery: food[userQuery]}}}
            )
    

    您希望将类别的实际字典(篮子的实际内容)与所选项目的键值合并。 通常在 python3 中,如果您有 2 个字典,这是将它们合并为一个的方法:

    d1 = {"one": 1, "two": 2}
    d2 = {"three": 3}
    merged = {**d1, **d2}  # {'one': 1, 'two': 2, 'three': 3}
    

    因为**是用来解包字典的。

    理解它的好方法是,如果您有一个带有一些参数的函数定义,那么您可以使用以参数名称作为键的字典来调用该函数。但是你必须解压它,否则你会将字典作为参数传递,而不是它的值。

    d = {"one": 1, "two": 2}
    def example(one, two):
        pass
    

    example(d) 会抛出 TypeError,因为它缺少第二个位置参数,但 example(**d) 可以正常工作

    【讨论】:

    • 这非常适合我的目的。我对 basketDict.update() 的内容和结构感到有些困惑——我不熟悉 () 中的“**”或内容结构。您能否提供解释或指向我可以了解其功能的资源?感谢您的解决方案。
    • 我做了一些更改以更清晰。此外,您不必使用方法update,只需设置键的值:basketDict[category] = {**basketDict.get(category, {}), **{userQuery: food[userQuery]}}
    【解决方案2】:

    可能有更简单的方法可以做到这一点,但我只是修复了您的代码。 当我运行您的代码时,shopDict 中的所有内容都将转到basketDict。这是因为您没有在每次 for 迭代时清理您的 shopCheck 变量。 在将元素添加到basketDict 时出现了第二个错误。您只需添加与userQuery 匹配的food 元素。这是完整的固定代码:

    basketDict = {}
    shopDict = {"Fruit": {"Apple": "2", "Banana": "3"},
                "Vegetables": {"Lettuce": "5", "Potato": "7"}}
    
    userQuery = input("What food do you want to check for? ")
    for category, food in shopDict.items():
        shopCheck = []
        for each in food:
            shopCheck.append(each)
    
        if userQuery not in shopCheck:
            print("That's not available.")
        else:
            print(userQuery + " added to basket. ")
            basketDict[category] = {userQuery:food[userQuery]}
    
    print(basketDict)
    

    【讨论】:

    • 我猜这也有缩进问题
    • 感谢您的回复。当我运行此代码并输入“Apple”时,它错误地产生“那不可用”。尽管成功地将其添加到了 basketDict。任何想法为什么?
    • @MHSalehi 实际上,如果您仔细分析代码,您会发现这不是错误。由于shopDict 有两对键值对(在本例中为类别-食物对),因此外部for 将执行两次:一次用于键“Fruit”,另一次用于键“Vegetables”。第二次迭代生成该打印,因为“蔬菜”值中确实不存在Apple,这是完全正确的。
    【解决方案3】:

    我首先创建一个字典,其中包含您可以购买的所有物品,无论是水果还是蔬菜。然后我只需检查所需的项目是否在该字典中:

    basketDict = {}
    shopDict = {"Fruit": {"Apple": "2", "Banana": "3"},
                 "Vegetables": {"Lettuce": "5", "Potato": "7"}}
    allVals = {}
    
    for k, subDict in shopDict.items():
        for k1, val in subDict.items():
            allVals[k1] = val
    
    
    userQuery = input("What food do you want to check for? ")
    if userQuery not in allVals.keys():
        print("That's not available.")
    else:
        print(userQuery + " added to basket. ")
        basketDict[userQuery] = allVals[userQuery]
    
    print(basketDict)
    

    【讨论】:

    • AttributeError: 'dict' 对象没有属性 'iteritems'
    • 哎呀,对不起,我用 python2.7 测试了这个。我会解决这个问题!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-07
    • 2021-12-29
    • 2016-10-21
    • 1970-01-01
    相关资源
    最近更新 更多