2010-05-06 15 views
8

En python, ¿cómo puedo resumir el tiempo siguiente?Pitón sumando tiempo

0:00:00 
0:00:15 
9:30:56 
+0

Supongo que desea sumar las diferencias de 0:00:00? es decir, los deltas, en lugar de los tiempos reales? –

+0

@steve: bueno, los deltas sumarían '9: 30: 56' – SilentGhost

+0

estoy usando python 2.4 y no puedo usar strptime, sí quiero sumar los deltas y para el ejemplo mencionado la respuesta debería ser 9 : 31: 11 – Hulk

Respuesta

9

¿Como una lista de cadenas?

timeList = [ '0:00:00', '0:00:15', '9:30:56' ] 
totalSecs = 0 
for tm in timeList: 
    timeParts = [int(s) for s in tm.split(':')] 
    totalSecs += (timeParts[0] * 60 + timeParts[1]) * 60 + timeParts[2] 
totalSecs, sec = divmod(totalSecs, 60) 
hr, min = divmod(totalSecs, 60) 
print "%d:%02d:%02d" % (hr, min, sec) 

Resultado:

9:31:11 
+0

Tenía esto en una matriz como las cadenas descritas .. Gracias .... – Hulk

+0

+1 solo por dar 'divmod()' a alguien en el aire ... lástima que nadie haya sido lo suficientemente valiente como para solicitar GvR para implementar '/%' y '/% =' operadores ;-) ... lee esto y llora: 'mins, secs /% = 60; horas, minutos /% = 60; días, horas /% = 24' –

+4

@John: personalmente considero que es ilegible. Debes recordar qué cosa en el LHS es el dividendo de entrada. También crea un caso en el que un operador devuelve una tupla, lo que impide operaciones de encadenamiento, que es el objetivo de los operadores binarios. Encuentro el camino 'divmod' mucho * más claro. –

2

Suponiendo que se desea sumar los segundos durante un tiempo total:

def parse_time(s): 
    hour, min, sec = s.split(':') 
    try: 
     hour = int(hour) 
     min = int(min) 
     sec = int(sec) 
    except ValueError: 
     # handle errors here, but this isn't a bad default to ignore errors 
     return 0 
    return hour * 60 * 60 + min * 60 + sec 

print parse_time('0:00:00') + parse_time('0:00:15') + parse_time('9:30:56') 
0

enfoque ingenuo (sin manejo de excepciones):

#!/usr/bin/env python 

def sumup(*times): 
    cumulative = 0 
    for t in times: 
     hours, minutes, seconds = t.split(":") 
     cumulative += 3600 * int(hours) + 60 * int(minutes) + int(seconds) 
    return cumulative 

def hms(seconds): 
    """Turn seconds into hh:mm:ss""" 
    hours = seconds/3600 
    seconds -= 3600*hours 
    minutes = seconds/60 
    seconds -= 60*minutes 
    return "%02d:%02d:%02d" % (hours, minutes, seconds) 

if __name__ == '__main__': 
    print hms(sumup(*("0:00:00", "0:00:15", "9:30:56"))) 
    # will print: 09:31:11 
19

Depende del formulario que tenga estos tiempos en, por ejemplo, si ya los tiene como datetime.timedelta s, entonces usted podría resumirlas:

>>> s = datetime.timedelta(seconds=0) + datetime.timedelta(seconds=15) + datetime.timedelta(hours=9, minutes=30, seconds=56) 
>>> str(s) 
'9:31:11' 
+2

Creo que esta es la solución más correcta usando deltas – dassouki

2
lines = ["0:00:00", "0:00:15", "9:30:56"] 
total = 0 
for line in lines: 
    h, m, s = map(int, line.split(":")) 
    total += 3600*h + 60*m + s 
print "%02d:%02d:%02d" % (total/3600, total/60 % 60, total % 60) 
+0

Ummmm esto está etiquetado como 'Python' no' awk'; '3600 *" 0 "' no se calculará; necesitas usar 'int()'; necesita probar cosas antes de publicarlo –

+0

He añadido 'map (int' – jfs

+0

@John ¡Vaya! Tiene razón. – Bolo

5

Estoy muy decepcionado si no hay ninguna solución más Pythonic ... :(

horrible one ->

timeList = [ '0:00:00', '0:00:15', '9:30:56' ] 

ttt = [map(int,i.split()[-1].split(':')) for i in timeList] 
seconds=reduce(lambda x,y:x+y[0]*3600+y[1]*60+y[2],ttt,0) 
#seconds == 34271 

Ésta se ve horrible también ->

zero_time = datetime.datetime.strptime('0:0:0', '%H:%M:%S') 
ttt=[datetime.datetime.strptime(i, '%H:%M:%S')-zero_time for i in timeList] 
delta=sum(ttt,zero_time)-zero_time 
# delta==datetime.timedelta(0, 34271) 

# str(delta)=='9:31:11' # this seems good, but 
# if we have more than 1 day we get for example str(delta)=='1 day, 1:05:22' 

realmente frustrante también es este ->

sum(ttt,zero_time).strftime('%H:%M:%S') # it is only "modulo" 24 :( 

Me gustaría ver una sola línea de modo, que trató de hacer una en python3: P (buen resultado, pero verse horrible)

import functools 
timeList = ['0:00:00','0:00:15','9:30:56','21:00:00'] # notice additional 21 hours! 
sum_fnc=lambda ttt:(lambda a:'%02d:%02d:%02d' % (divmod(divmod(a,60)[0],60)+(divmod(a,60)[1],)))((lambda a:functools.reduce(lambda x,y:x+y[0]*3600+y[1]*60+y[2],a,0))((lambda a:[list(map(int,i.split()[-1].split(':'))) for i in a])(ttt))) 
# sum_fnc(timeList) -> '30:40:11' 
8

Usando timedeltas (probado en Python 3.4):

import datetime 

timeList = ['0:00:00', '0:00:15', '9:30:56'] 
sum = datetime.timedelta() 
for i in timeList: 
    (h, m, s) = i.split(':') 
    d = datetime.timedelta(hours=int(h), minutes=int(m), seconds=int(s)) 
    sum += d 
print(str(sum)) 

Resultado:

9:31:11 
+0

También funciona en 2.7. +1 porque el código es legible e intuitivo – adelval

0

Bellow es una solución utilizando reducir y comprensión de lista:

from functools import reduce 
from datetime import timedelta 

time_list = ['0:00:00', '0:00:15', '9:30:56'] 

total = reduce(lambda x, y: x + y, 
     [timedelta(hours=int(ms[0]), minutes=int(ms[1]), seconds=int(ms[2])) 
      for t in time_list 
       for ms in [t.split(':')]]) 

print(f'Total time: {total}') 

Tiempo total: 9:31:11