简体   繁体   English

如何在 Python 的嵌套字典列表中查找键的值

[英]How to find the values of a key in a nested list of dictionaries in Python

This is my data structure.这是我的数据结构。 I have 3000 instances of 'product' within the 'clothes list'.我在“衣服列表”中有 3000 个“产品”实例。 Each contains another list of dictionaries that stores the reviews.每个都包含另一个存储评论的字典列表。

clothes_list = 
[
  {
    "ID": "1000201",
    "Name": "Clothes Name",
    "Price": 24.1,
    "Category": "Trousers"
    "Reviews": [{'User': 'username1200', 'Review': 'some review', 'Score': 2}
                  {'User': 'username341', 'Review': 'Some review 2' , 'Score': 4}
                  {'User': 'username34841', 'Review': 'Some review 3' , 'Score': 2}
               ]
  },

  {
    "ID": "1003801",
    "Name": "Clothes Name",
    "Price": 29.1,
    "Category": "Trousers"
    "Reviews": [{'User': 'username1200', 'Review': 'some review', 'Score': 2}
                  {'User': 'username341', 'Review': 'Some review 4' , 'Score': 7}
                  {'User': 'username34841', 'Review': 'Some review 5' , 'Score': 4}
               ]
  },
  
]

I am attempting to iterate through all the reviews in the dictionary and return all the reviews written by a particular username.我正在尝试遍历字典中的所有评论并返回由特定用户名撰写的所有评论。

My Two attempts below output the same error.我在 output 下面的两次尝试同样的错误。

username = "username341"
reviews = next((review for review in clothess_list if review["Reviews"]["User"] == username))]
values = [a_dict["Reviews"][username] for a_dict in clothes_list]

The Error错误

TypeError: list indices must be integers or slices, not str TypeError:列表索引必须是整数或切片,而不是 str

Target Output目标 Output

{'User': 'username341', 'Review': 'Some review 2' , 'Score': 4}, 
{'User': 'username341', 'Review': 'Some review 4' , 'Score': 7}

Your logic review["Reviews"]["User"] can't be iterable because Reviews is a list of dictionaries.您的逻辑 review[" Reviews review["Reviews"]["User"]不能迭代,因为 Review 是一个字典列表。 You can't directly call dictionary without putting any index of list.您不能直接调用字典而不放置任何列表索引。

username = "username341"
reviews=next( user for review in clothes_list for user in review['Reviews'] if user['User']==username)
    
print(reviews)

Output Output

{'User': 'username341', 'Review': 'Some review 2', 'Score': 4}

Your attempts are incorrect because you are treating a list as a dictionary.您的尝试不正确,因为您将列表视为字典。 The following snippet solves your problem, but it is probably not the best way to do so.以下代码段解决了您的问题,但这可能不是最好的方法。

reviews = next(
    c for c in clothes_list 
    if any(review for review in c["Reviews"] if review["User"] == username)
)

I find it easiest just to write it across multiple lines as if I were writing multiple for loops我发现最简单的方法是跨多行编写它,就好像我在编写多个 for 循环一样

[review
 for clothes_item in clothes_list
 for review in clothes_item["Reviews"]
 if review["User"] = username
]

You can of course turn this into a generator if want by replacing the [] with ()如果需要,您当然可以通过将[]替换为()来将其变成生成器

Try this:尝试这个:

clothes_list = [{
    "ID": "1000201",
    "Name": "Clothes Name",
    "Price": 24.1,
    "Category": "Trousers",
    "Reviews": [{
        "User": "username1200", "Review": "some review", "Score": 2
    }, {'User': 'username341', 'Review': 'Some review 2', 'Score': 4},
        {'User': 'username34841', 'Review': 'Some review 3', 'Score': 2},{
        "User": "username1200", "Review": "some review 4 by same user", "Score": 2
    },]
}]


def get_reviews(username):
    a = []
    for i in range(len(clothes_list)):
        for x in clothes_list[i]["Reviews"]:
            if x["User"] == username:
                a.append(x)

    return a

print(get_reviews("username1200"))

Everyone else's answers are also correct, just the dataset contains only one review from each user.其他人的答案也是正确的,只是数据集只包含每个用户的一条评论。 I have editted the dataset to contain 2 reviews from username1200我已编辑数据集以包含来自 username1200 的 2 条评论

Try the other answers with the dataset i have provided and it'll return 2 dicts in a list.使用我提供的数据集尝试其他答案,它将在列表中返回 2 个字典。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM