在 Python 中尝试使用列表推导式过滤字典列表时出现问题

Issue when trying to filter dictionary list using list comprehension in Python

我想从一个字典列表中过滤出来,例如下面相应项的列表,其中 fileNameobjectAttribute 的值中是 tree 并且没有以下值: green-fieldsnowy-fieldyellow-field

array = [
    {'fileName': 'waterfall_074', 'objectAttribute': 'black-cliff'},
    {'fileName': 'waterfall_074', 'objectAttribute': 'waterfall'}, 
    {'fileName': 'waterfall_074', 'objectAttribute': 'black-cliff'}, 
    {'fileName': 'opencountry_test_010', 'objectAttribute': 'red-flower'}, 
    {'fileName': 'opencountry_test_010', 'objectAttribute': 'overcast-sky'}, 
    {'fileName': 'highway_bost183', 'objectAttribute': 'cloudy-sky'}, 
    {'fileName': 'highway_bost183', 'objectAttribute': 'tree'},
    {'fileName': 'highway_bost183', 'objectAttribute': 'tree'},
    {'fileName': 'highway_bost183', 'objectAttribute': 'road'},
    {'fileName': 'opencountry_076', 'objectAttribute': 'cloudy-sky'}, 
    {'fileName': 'opencountry_076', 'objectAttribute': 'yellow-field'}, 
    {'fileName': 'opencountry_092', 'objectAttribute': 'overcast-sky'}, 
    {'fileName': 'opencountry_092', 'objectAttribute': 'tree'},
    {'fileName': 'opencountry_092', 'objectAttribute': 'yellow-field'}, 
    {'fileName': 'opencountry_092', 'objectAttribute': 'green-field'},
    {'fileName': 'mountain_086', 'objectAttribute': 'dusthaze-sky'},
    {'fileName': 'mountain_086', 'objectAttribute': 'rocky-mountain'},
    {'fileName': 'ibis_001', 'objectAttribute': 'black-ibis'},
    {'fileName': 'ibis_001', 'objectAttribute': 'green-field'},
    {'fileName': 'ibis_001', 'objectAttribute': 'green-field'},
    {'fileName': 'bison08', 'objectAttribute': 'tree'},
    {'fileName': 'bison08', 'objectAttribute': 'black-bison'},
    {'fileName': 'bison08', 'objectAttribute': 'green-field'},
    {'fileName': 'volcano_0191', 'objectAttribute': 'dusthaze-sky'},
    {'fileName': 'volcano_0191', 'objectAttribute': 'rocky-mountain'}, 
    {'fileName': 'horse_097', 'objectAttribute': 'tree'},
    {'fileName': 'horse_097', 'objectAttribute': 'white-horse'},
    {'fileName': 'horse_097', 'objectAttribute': 'green-field'}
]

从上面的这个列表中有另一个项目列表,有 tree 作为 objectAttribute ['opencountry_092', 'horse_097', 'highway_bost183', 'bison08'] 并且您可以检查此列表中唯一没有任何这些值的值:green-fieldsnowy-fieldyellow-fieldhighway_bost183

我想出了以下代码,但是它不起作用

def busca_images(array):
  print(array)
  arrayFiltered = [n for n in array if 'tree' in n['objectAttribute'] ]
  newSet = set()
  for e in arrayFiltered:
    newSet.add(e['fileName'])
    files = []
  for e in newSet:
    if len([n for n in array if 'green-field' in n['objectAttribute'] or 'snowy-field' in n['objectAttribute'] or 'yellow-field' in n['objectAttribute'] ]) != 0: files.append(e)
  print(list(files))

我认为这个条件错误就在这里...

if len([n for n in array if 'green-field' in n['objectAttribute'] or 'snowy-field' in n['objectAttribute'] or 'yellow-field' in n['objectAttribute'] ]) != 0: files.append(e)
def busca_images(array):
    has_tree = set()
    has_field = set()
    final = set()
    for each in array:
        if each['objectAttribute'] == 'tree':
            has_tree.add(each['fileName'])
    for each in array:
        if each['fileName'] in has_tree and each['objectAttribute'] in ['green-field', 'yellow-field', 'snowy-field']:
            has_field.add(each['fileName'])
    return list(has_tree - has_field)[0]
print(busca_images(array))

这不是最优雅的方法,可能有一种无需循环列表两次的更快的方法。

但简单地说:

  • 循环列表以查找树,添加到 has_tree 集
  • 再次循环查找字段,添加到has_fields集合
  • 从has_tree中减去has_field得到值

输出:'highway_bost183'

这样做让我思考。如果只有一个字典,以文件名作为键,然后以属性列表作为值,不是更好吗?这将使这个过程更容易。