Home > Enterprise >  Handling NoneType or empty list indices when iterating through variable lists
Handling NoneType or empty list indices when iterating through variable lists

Time:06-10

I have a function measure_amount() that returns a dict inside a list with a specific 'total' amount from an obj if the amount exists. Example:

[{'unit': 'foo', 'total': Decimal('5900.00'), 'type': None}]

When iterating through measurement on multiple objects, the dict-in-list is variable and there may or may not be a 'total' or the list may be empty. Sometimes the function willreturn an empty list:

[]

My original code was:

for o in objects:
    l = o.measure_amount()
    # use enumerate to get the index for 'total' if it exists
    i = next((index for (index, d) in enumerate(l) if d["total"]), None)
    amount = l[i]["total"]
    total_amount  = amount

return total_amount

This works for when "total" exists in the index but throws an err when the list is empty because in the index is None:

TypeError: list indices must be integers or slices, not NoneType 

I can use an if statement to check if i is not None: as a condition before amount = l[i]["total"] but I'm wondering from a pythonic perspective - is there a better way to handle this type of list variability? thanks

CodePudding user response:

Use exceptions, in the spirit on Python's: ask for forgiveness, not for permission.

for o in objects:
    l = o.measure_amount()
    try:
        # use enumerate to get the index for 'total' if it exists
        i = next((index for (index, d) in enumerate(l) if d["total"]), None)
        amount = l[i]["total"]
        total_amount  = amount
    except (KeyError, TypeError):
        pass

return total_amount

CodePudding user response:

You could just use dict.get on the total key with a default value of Decimal(0) for each dictionary in l, and then just sum the results:

l = [
 {'unit': 'bar', 'type': None},
 {'unit': 'foo', 'total': Decimal('5900.00'), 'type': None}
]
sum(d.get('total', Decimal(0)) for d in l)

Output:

Decimal('5900.00')
  • Related