在以事件类型为键的命名元组的字典列表中搜索子字符串

Search substring in list of dictionaries of namedtuples keyed with an event type

我创建了一个命名元组字典列表,以事件类型为键。

[{'EVENT_DELETE': DeleteRequestDetails(rid=53421, user='user1', type='EVENT_DELETE', reviewed=1, approved=1, completed=0)},{'EVENT_DELETE': DeleteRequestDetails(rid=13423, user='user2', type='EVENT_DELETE', reviewed=1, approved=1, completed=0)},{'EVENT_DELETE': DeleteRequestDetails(rid=98343, user='user2', type='EVENT_DELETE', reviewed=1, approved=0, completed=0)}]

return/print 仅包含“approved=1”或“reviewed=1”和“approved=0”的结果的最 pythonic 方法是什么?

这里有一个可能的解决方案:

# data = [{'EVENT_DELETE': DeleteRequestDetails(rid=53421, user='user1', type='EVENT_DELETE', reviewed=1, approved=1, completed=0)},{'EVENT_DELETE': DeleteRequestDetails(rid=13423, user='user2', type='EVENT_DELETE', reviewed=1, approved=1, completed=0)},{'EVENT_DELETE': DeleteRequestDetails(rid=98343, user='user2', type='EVENT_DELETE', reviewed=1, approved=0, completed=0)}]

res = filter(
    lambda _: _.approved == 1 or (_.reviewed == 1 and _.approved == 0),
    (b for a in data for b in a.values())
)
print(next(res))
# DeleteRequestDetails(rid=53421, user='user1', type='EVENT_DELETE', reviewed=1, approved=1, completed=0)

基本上,我们只是内置 filter 函数并使用自定义 (lambda-) 函数。

请注意,过滤器 returns 是一个类似生成器的对象。例如,您可以将其包装在 list 中您需要多次访问数据。


PS

正如@PatrickArtner 所指出的,拥有一个包含 1 个值的字典列表没有意义。这样的事情更有意义:

data = {
    "EVENT_DELETE": [
        DeleteRequestDetails(rid=53421, user='user1', type='EVENT_DELETE', reviewed=1, approved=1, completed=0),
        DeleteRequestDetails(rid=13423, user='user2', type='EVENT_DELETE', reviewed=1, approved=1, completed=0),
        DeleteRequestDetails(rid=98343, user='user2', type='EVENT_DELETE', reviewed=1, approved=0, completed=0)
    ]
}

这使得解决方案也更加清晰和简单,因为无需循环遍历值,例如

res = filter(
    lambda _: _.approved == 1 or (_.reviewed == 1 and _.approved == 0),
    data["EVENT_DELETE"]
)

不确定您想要什么输出格式,但这是 approved == 1 的演示。

>>> from collections import namedtuple
>>> DeleteRequestDetails = namedtuple('DeleteRequestDetails', 'rid user type reviewed approved completed')
>>> lst = [{'EVENT_DELETE': DeleteRequestDetails(rid=53421, user='user1', type='EVENT_DELETE', reviewed=1, approved=1, completed=0)},{'EVENT_DELETE': DeleteRequestDetails(rid=13423, user='user2', type='EVENT_DELETE', reviewed=1, approved=1, completed=0)},{'EVENT_DELETE': DeleteRequestDetails(rid=98343, user='user2', type='EVENT_DELETE', reviewed=1, approved=0, completed=0)}]
>>> [v for d in lst for v in d.values() if v.approved == 1] 
[DeleteRequestDetails(rid=53421, user='user1', type='EVENT_DELETE', reviewed=1, approved=1, completed=0),
 DeleteRequestDetails(rid=13423, user='user2', type='EVENT_DELETE', reviewed=1, approved=1, completed=0)]