2017-09-02 2 views
1

Ich habe die folgende Liste von Zeitschlitzen (start_date, end_date), nach Startdatum sortiert:Vergleichen Zeitschlitze in Python

slots = [(datetime.datetime(2017, 10, 2, 6, 0), datetime.datetime(2017, 10, 2, 17, 40)), 
(datetime.datetime(2017, 10, 2, 10, 35), datetime.datetime(2017, 10, 2, 16, 25)), 
(datetime.datetime(2017, 10, 2, 11, 0), datetime.datetime(2017, 10, 2, 12, 0)), 
(datetime.datetime(2017, 10, 2, 12, 0), datetime.datetime(2017, 10, 2, 13, 0)), 
(datetime.datetime(2017, 10, 2, 15, 0), datetime.datetime(2017, 10, 2, 16, 0)), 
(datetime.datetime(2017, 10, 2, 18, 0), datetime.datetime(2017, 10, 2, 19, 0))] 

Ich möchte alle Zeitschlitze mit einem Startdatum und ein Enddatum entfernen enthalten in einem anderen Zeitfenster diese Liste präsentieren.

So, hier zum Beispiel sollte das Endergebnis sein:

slots = [(datetime.datetime(2017, 10, 2, 6, 0), datetime.datetime(2017, 10, 2, 17, 40)), 
(datetime.datetime(2017, 10, 2, 18, 0), datetime.datetime(2017, 10, 2, 19, 0))] 

Ich habe versucht, es mit der folgenden Funktion zu reduzieren, aber es funktioniert nicht:

reduce(slots_removal, slots) 

def slots_removal(a, b): 
    if a[1] > b[1]: 
     del b 

Dies erzeugt :

TypeError: 'NoneType' object has no attribute '__getitem__'" 
+0

Ist Ihre Eingabe immer sortiert? Was ist mit partiellen Überlappungen (Start ist vor Ende eines vorherigen Eintrags, aber Ende ist danach)? –

+0

Hi @MartijnPieters, ja ich sortiere die Eingabe, um es einfacher zu machen, danach mit 'slots = sorted (current_schedule, key = lambda x: x [0]) zu filtern So kann Start vor Ende eines vorherigen Eintrags sein und enden nach, aber es sollte nicht das Ergebnis beeinflussen, nein? – chdecultot

Antwort

1

Wenn Sie Ihre Eingabe immer sortiert ist, können Sie einfach einen Generator-Funktion:

import datetime 

def reduced(timeseries): 
    prev = datetime.datetime.min 
    for start, end in timeseries: 
     if end > prev: 
      prev = end 
      yield start, end 

dies nur Ausbeuten (start, end) Tupeln wenn end später als das previousy Tupel ergibt.

Demo:

>>> list(reduced(slots)) 
[(datetime.datetime(2017, 10, 2, 6, 0), datetime.datetime(2017, 10, 2, 17, 40)), (datetime.datetime(2017, 10, 2, 18, 0), datetime.datetime(2017, 10, 2, 19, 0))] 
>>> from pprint import pprint 
>>> pprint(_) 
[(datetime.datetime(2017, 10, 2, 6, 0), 
    datetime.datetime(2017, 10, 2, 17, 40)), 
(datetime.datetime(2017, 10, 2, 18, 0), 
    datetime.datetime(2017, 10, 2, 19, 0))] 

Sie können reduce() nicht verwenden; Diese Funktion erzeugt ein einzelnes Ergebnis aus einer Eingabesequenz. Die Ausgabe der Funktion wird zur Eingabe für den nächsten Aufruf (zusammen mit dem nächsten Element); Da Ihre Funktion nicht explizit etwas zurückgibt, wird stattdessen None zurückgegeben und als Eingabe für den nächsten Aufruf verwendet.

+0

Danke eine Million, es funktioniert super !! Und danke für die Erklärung zur Funktion reduce()! – chdecultot