0

I have created a list of dictionaries of named tuples, 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)}]

What would be the most pythonic method to return/print results that only contain "approved=1", or "reviewed=1" and "approved=0"?

gosaultech
  • 89
  • 1
  • 8
  • Depends on how exactly your want the output to look like. – timgeb Dec 23 '21 at 11:38
  • 1
    having those dictionaries does **nothing** for you - it only uses more memory. You only ever have 1 element per dict. to get all values of a dict where the value has a property that does x: you need to traverse the whole list, look into each dict. for each key in the dict get the value and check the value. Loops will do it. llist comp will do it - I wont do it for you. What did you try and where are you stuck? – Patrick Artner Dec 23 '21 at 11:38

2 Answers2

2

Here would be a possible solution:

# 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)

Basically, we just the builtin filter function and use a custom (lambda-) function.

Note that filter returns a generator-like object. You can wrap it in list if e.g. you need to access the data multiple times.


PS

As @PatrickArtner pointed out, having a list of dicts w/ 1 value doesn't make sense. Something like this makes more sense:

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)
    ]
}

This makes the solutions also much cleaner and simpler as there is no need to loop through values, e.g.

res = filter(
    lambda _: _.approved == 1 or (_.reviewed == 1 and _.approved == 0),
    data["EVENT_DELETE"]
)
niko
  • 5,253
  • 1
  • 12
  • 32
  • Thanks for your and @PatrickAtner's feedback on this. I've switched to using "user" instead of event type as the element since this will always contain more than one value and is more suitable for the end use case. – gosaultech Dec 23 '21 at 11:57
2

Not sure what output format you want exactly, but here's a demo for 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)]
timgeb
  • 76,762
  • 20
  • 123
  • 145
  • I consider this the accepted answer since this is the type of filtering via list comprehension along with output that I was looking for. – gosaultech Dec 23 '21 at 11:58