-1

In Python, what is the easiest way to get the total count of one field from a set of named tuples?

In this example, I'm looking for the total count of TestResults.failed, which should be 4. It's doable with a for loop, but it feels like there could be a more efficient way.

from collections import namedtuple

TestResults = namedtuple('TestResults', ['failed', 'attempted'])

test_results = [
    TestResults(0, 5),
    TestResults(3, 28),
    TestResults(1, 7)
]

failed_count = 0
for r in test_results:
    if hasattr(r, 'failed'):
        failed_count += r.failed

print(failed_count)
4
  • Are you looking for sum(i.failed for i in test_results)?
    – user459872
    Commented Feb 15 at 12:03
  • And also why hasattr(r, 'failed') in your for loop?
    – user459872
    Commented Feb 15 at 12:06
  • Does this answer your question? Sum / Average an attribute of a list of objects Commented Feb 15 at 12:08
  • @AbdulNiyasPM - I was using hasattr() because in reality the named tuple comes from a 3rd party module, and I wanted to be sure I didn't get any errors if the field I was checking didn't exist. I've since inspected that module and can see that the field is required anyway, so the check is irrelevant and thus not required. Thanks.
    – David Gard
    Commented Feb 15 at 12:38

1 Answer 1

2

With arbitrary objects, you can use getattr with 0 as a default value, and use sum with a generator expression:

sum(getattr(res, 'failed', 0) for res in test_results)

Since you have namedtuples with no optional values, you can get the values directly using dot notation:

sum(res.failed for res in test_results)

If you have a namedtuple with an optional 'failed' field, if the optional value is 0, then the above should work, otherwise, if the optional value is None, you could use this to use 0 as a default value:

sum(res.failed or 0 for res in test_results)
3
  • Why would you need to use getattr when the objects are all a namedtuple guaranteed to have a failed attribute? Commented Feb 15 at 12:12
  • @AbdulAzizBarkat you're right, I was first assuming optional values, but even in that case the field would still exist.
    – Djaouad
    Commented Feb 15 at 12:19
  • @DjaouadNM - Thanks for you answer, your middle option works perfectly for my use case and saves some lines of code.
    – David Gard
    Commented Feb 15 at 12:35

Not the answer you're looking for? Browse other questions tagged or ask your own question.