2010-11-07 22 views
7

Tengo una lista con los siguientes elementos:la hora más cercana

hours = ['19:30', '20:10', '20:30', '21:00', '22:00'] 

Suponiendo que ahora es 20:18, ¿cómo puedo obtener el '20: 10' elemento de la lista? Quiero usar esto para encontrar el espectáculo en ejecución actual en una guía de TV.

+3

lo probaste? ¿Por qué no funcionó? – carlosdc

+1

¿Qué enfoques has probado hasta ahora que no funcionan? –

+2

¿Qué resultado quieres si ahora son las 20:25? 20:30 es el más cercano, pero está en el futuro, por lo que no puede ser el espectáculo en ejecución actual ... –

Respuesta

8
>>> import datetime 
>>> hours = ['19:30', '20:10', '20:30', '21:00', '22:00'] 
>>> now = datetime.datetime.strptime("20:18", "%H:%M") 
>>> min(hours, key=lambda t: abs(now - datetime.datetime.strptime(t, "%H:%M"))) 
'20:10' 
+2

+1 por hacer lo que el OP ha pedido (encontrar la hora más cercana), pero también escribió que quiere encontrar el "espectáculo actual", así que para '20: 22' obtienes' 20: 30' que obviamente no es el programa actualmente en ejecución. –

1

Puede usar funciones en el módulo de tiempo; time.strptime() le permite analizar una cadena en una tupla de tiempo, luego time.mktime() lo convierte en segundos. Luego puede simplemente comparar todos los elementos en segundos y encontrar la diferencia más pequeña.

1
import bisect 
# you can use the time module like katrielalex answer which a standard library 
# in python, but sadly for me i become an addict to dateutil :) 
from dateutil import parser 

hour_to_get = parser.parse('20:18') 

hours = ['19:30', '20:10', '20:30', '21:00', '22:00'] 
hours = map(parser.parse, hours) # Convert to datetime. 

hours.sort() # In case the list of hours isn't sorted. 

index = bisect.bisect(hours, hour_to_get) 

if index in (0, len(hours) - 1): 
    print "there is no show running at the moment" 
else: 
    print "running show started at %s " % hours[index-1] 

Hope esto le puede ayudar :)

+2

Esto supone que los tiempos con un dígito de horas o minutos se representan con un cero a la izquierda para los valores respectivos. –

+0

puede convertirlos desde el principio antes de llamar a bisect.bisect – mouad

+0

bisect funciona si la lista está ordenada. Considere 'horas = ['19: 30 ', '20: 10', '20: 30 ', '23: 00', '21: 00 ', '22: 00']' – khachik

2

No soy un programador de Python, pero me gustaría utilizar el siguiente algoritmo:

  1. Convertir todo a "minutos después de la medianoche" , p.ej hours = [1170 (= 19*60+30), 1210, ...], currenttime = 1218 (= 20*60+18).

  2. Luego solo bucle thorugh hours y encuentre la última entrada que es más pequeña que currenttime.

+0

+1: Esto realmente resolvería el problema del "espectáculo que se está ejecutando actualmente". Tal vez sea necesario ordenar los tiempos primero. –

1

@katrielalex & Tim

import itertools 
[x for x in itertools.takewhile(lambda t: now > datetime.datetime.strptime(t, "%H:%M"), hours)][-1] 
5

manera fácil pero sucio

max(t for t in sorted(hours) if t<=now) 
Cuestiones relacionadas