-3

Given the following list:

times = [datetime.timedelta(0, 1, 256273), datetime.timedelta(0, 0, 910417), datetime.timedelta(0, 0, 388175)]

How would I get the average of times? Doing the following gives me an error:

avg = (float(sum(times)) / len(times))
TypeError: unsupported operand type(s) for +: 'int' and 'datetime.timedelta'
David542
  • 104,438
  • 178
  • 489
  • 842

2 Answers2

7

There are two problems here:

  • sum() starts out the summing with an integer 0. You cannot add a timedelta() object to an integer, so you get an error:

    >>> import datetime
    >>> times = [datetime.timedelta(0, 1, 256273), datetime.timedelta(0, 0, 910417), datetime.timedelta(0, 0, 388175)]
    >>> sum(times)
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: unsupported operand type(s) for +: 'int' and 'datetime.timedelta'
    
  • Even if you could just use sum() outright, you cannot convert a timedelta() object to a float() by passing it to the float() function:

    >>> float(datetime.timedelta())
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: float() argument must be a string or a number
    

You need to tell sum() to start with an empty timedelta (start at timedelta(0)) and use the timedelta.total_seconds() function to get a floating point number:

>>> sum(times, datetime.timedelta())
datetime.timedelta(0, 2, 554865)
>>> sum(times, datetime.timedelta()).total_seconds()
2.554865
>>> sum(times, datetime.timedelta()).total_seconds() / len(times)
0.8516216666666666

You can omit the .total_seconds() part and get another timedelta() object:

>>> sum(times, datetime.timedelta()) / len(times)
datetime.timedelta(0, 0, 851621)

which is going to be more accurate. You can always call .total_seconds() after the division:

>>> (sum(times, datetime.timedelta()) / len(times)).total_seconds()
0.851621
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
0

Another option is to use list comprehension to get a list of floats, which can be summed:

avg = sum([t.total_seconds() for t in times]) / len(times)

# avg == 0.851621666667

But as Martijn said, it is more accurate to sum timedelta objects together, starting from an empty one.

tavnab
  • 2,594
  • 1
  • 19
  • 26