So I have this list:
[datetime.timedelta(0, 1800), datetime.timedelta(0, 1800), datetime.timedelta(0, 1800), datetime.timedelta(0, 1800)]
Collectively that is 2:00 hours. I'm trying to add those up to get 2:00 time delta, which then in turn needs to be turned into a string of 2.0 Hours. Respectively 1:30 Hours would be 1.5 Hours as the final countdown.
The naive approach would be to take the seconds
from each object and sum
them
>>> a = [datetime.timedelta(0, 1800)] * 4
>>> print sum([d.seconds for d in a])
7200
>>> print sum([d.seconds for d in a]) / 60.0 / 60.0
2.0
but this is not as robust as Haidro's solution:
import operator
reduce(operator.add, a)
This results in a timedelta
object with the correct delta that you can use however you want.
The obvious way to sum anything number-like and addable in Python is with the sum
function:
>>> dts = [datetime.timedelta(0, 1800), datetime.timedelta(0, 1800), datetime.timedelta(0, 1800), datetime.timedelta(0, 1800)]
>>> sum(dts, start=datetime.timedelta(0))
datetime.timedelta(0, 9, 933279)
(For most number-like types, you don't even need the start
value, because they know how to add themselves to 0
. timedelta
explicitly does not allow this, to avoid accidentally mixing dimensionless intervals—e.g., you don't want to add timeout_in_millis
to a timedelta
…)
Whenever you're using reduce
with operator.add
for number-like values, you're probably doing it wrong.
If you don't provide an initial
argument to reduce
, it will do the wrong thing with an empty list, raising a TypeError
instead of returning the 0
value. (The sum of no numbers is 0; the sum of no timedelta
s is timedelta(0)
; etc.)
And if you do provide an initial
argument, then it's just a more verbose, more complicated, and slower way to write sum
. Compare:
functools.reduce(operator.add, a, foo(0))
sum(a, foo(0))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With