Python中嵌套字典列表的过滤与指定字段提取问题求助
解决Python嵌套字典列表的过滤与字段提取问题
嘿,刚接触Python遇到这种嵌套结构的问题很正常,咱们一步步来修正你的代码:
一、修正过滤逻辑的错误
你当前的filter代码里踩了个小坑:i['metadata']['tags']是列表类型,不是字典,所以不能直接用['attributes']去访问。我们需要遍历这个列表里的每一个tag元素,找到包含attributes键的那个字典,再检查里面的Background值。
修正后的过滤代码如下:
all_assets = [{'dateListed': 58391, 'id': '118572', 'metadata': {'files': [], 'mediaType': 'image/png', 'name': 'The three', 'tags': [{'right': '101 Galaxy'}, {'attributes': {'Background': 'Mars', 'Body': 'Rough', 'Face': 'Dumb', 'Headwear': 'Helmet'}}], 'thumbnail': 'something'}, 'Session': None, 'police': 'pewpew', 'verified': {'project': 'Thes', 'verified': True}}, {'dateListed': 430298239, 'id': '1191281', 'metadata': {'files': [], 'mediaType': 'image/png', 'name': 'TheOne', 'tags': [{'right': '101 Galaxy'}, {'attributes': {'Background': 'Star', 'Body': 'Smooth', 'Face': 'Fresh', 'Headwear': 'Cap'}}], 'thumbnail': 'something'}, 'Session': None, 'police': 'pewpew', 'verified': {'project': 'Thes', 'verified': True}}] search_attribute = 'Background' search_attribute_value = 'Star' # 修正后的过滤逻辑 filtered = filter( lambda asset: any( tag.get('attributes', {}).get(search_attribute) == search_attribute_value for tag in asset['metadata']['tags'] ), all_assets ) # 把filter返回的迭代器转成列表,方便后续多次使用 filtered_list = list(filtered) print(filtered_list)
这里的关键细节:
- 遍历
asset['metadata']['tags']里的每一个tag元素 - 用
tag.get('attributes', {})来避免找不到attributes键时抛出错误,默认返回空字典 - 再通过
.get(search_attribute)获取目标属性值,和你要找的Star对比 any()函数只要找到一个符合条件的tag,就会保留当前这个asset
二、修正字段提取的代码
你提取字段的代码里有几个语法和逻辑错误:
x.get('metadata')('name')是错误写法,get()返回的是字典,应该用字典的get方法来取值tags是列表,必须先找到包含attributes的那个tag,才能提取Headwear
修正后的遍历提取代码:
for x in filtered_list: asset_id = x.get('id') # 别用id当变量名,它是Python的内置函数,容易冲突 name = x.get('metadata', {}).get('name') # 遍历tags找到包含attributes的字典 attributes = None for tag in x.get('metadata', {}).get('tags', []): if 'attributes' in tag: attributes = tag['attributes'] break headwear = attributes.get('Headwear') if attributes else 'N/A' print(f'ID: {asset_id}') print(f'Name: {name}') print(f'Headwear: {headwear}')
这里的优化点:
- 避免使用
id作为变量名,防止覆盖Python内置的id()函数 - 用
.get(key, 默认值)的方式取值,就算某个键不存在也不会报错 - 专门遍历tags列表找到
attributes字典,确保能正确提取Headwear
最终运行结果
执行上面的代码后,过滤后的列表和你预期的完全一致,字段提取的输出也会是:
ID: 1191281 Name: TheOne Headwear: Cap
额外小建议
刚接触Python处理嵌套结构时,你可以先打印单个元素的结构(比如print(all_assets[0])),理清层级关系后再写代码,这样不容易踩坑。另外,用列表推导式实现过滤的写法可能更直观,和filter逻辑完全一致:
filtered_list = [ asset for asset in all_assets if any( tag.get('attributes', {}).get(search_attribute) == search_attribute_value for tag in asset['metadata']['tags'] ) ]
内容的提问来源于stack exchange,提问作者KeenEm
相关产品推荐
相关产品推荐

