2013-08-31 10 views
5

Ho una lista: il numeroTrova se un numero esiste tra una serie di numeri specificati da un elenco

timestamp_list = ['1377091800', '1377093000', '1377094500', '1377095500'] 

Obiettivo:

ptime = 1377091810 

voglio trovare tra i quali paio di timestamp fa ptime mentire. Per es in questo caso, si trova tra il primo e il secondo timestamp. Quindi voglio restituire il valore 1377091800 come output desiderato. Analogamente, se ptime era 1377091520, quindi voglio che venga restituito il terzo timestamp, ad esempio 1377091500 poiché si trova tra il terzo e il quarto timestamp.

Il mio codice:

timestamp_list = ['1377091800', '1377093000', '1377094500', '1377095500'] 
ptime = 1377091810 
for idx, value in enumerate(timestamp_list): 
    val = long(value) 
if idx!= len(timestamp_list)-1 and ptime >= val and ptime < long(timestamp_list[idx+1]): 
    target = val 
    break 
elif (idx == len(timestamp_list)-1) and ptime >= val: 
    target = val 
else: 
    pass 
print target 

uscita: 1377091800

Volevo sapere v'è alcuna soluzione elegante a questo? Dato che sto iniziando con Python, non ho ancora familiarità con tutte le funzioni di Python.

Qualsiasi aiuto è apprezzato.

EDIT:

soluzione utilizzata:

import bisect 
timestamp_list = ['1377091800', '1377093000', '1377094500', '1377095500'] 
ptime = str(1377093110) 
if ptime in timestamp_list: 
    target = ptime 
else: 
    index = bisect.bisect_right(timestamp_list, ptime)-1 
    target = timestamp_list[index] 
print target 

USCITA:

1377093000 
+0

l'elenco timestamp ordinato? –

+0

Qualcosa come '[x per x in tsl se x <= ptime] [-1]'? – Hyperboreus

+0

@MartijnPieters yes la lista timestamp è ordinata – Geekster

risposta

7

Dal momento che i timestamp sono ordinati, è possibile utilizzare bisect per questo:

In [24]: timestamp_list = [1377091800, 1377093000, 1377094500, 1377095500] 

In [25]: timestamp_list[bisect.bisect_right(timestamp_list, 1377093100)] 
Out[25]: 1377094500 

(ho convertito le corde per interi per mantenere il codice chiaro.)

+1

Inoltre, per usare 'bisect' è * avere * usare gli interi come ordinamento alfanumerico dei numeri non è necessariamente lo stesso di un ordinamento numerico, buttando' bisect' per certi casi di edgecases. Certo, per i timestamp, è improbabile che li colpisca, ma comunque. –

+1

E per completezza (dato che ho cancellato la mia risposta): 'bisect' prende O (log N) tempo, rispetto a O (N) per una scansione completa. In parole povere: molto più veloce. –

+0

Ho modificato la risposta di cui sopra in base al mio scopo. Dato che l'indice restituito dal modulo 'bisect' era superiore a quello dell'indice richiesto, l'ho decrementato per ottenere l'output desiderato. Aggiornare la mia domanda con la soluzione che ho usato. – Geekster

Problemi correlati