2010-09-01 68 views
10

我想計算列表中日期之間的avarage timedelta。 雖然以下工作很好,但我想知道是否有更聰明的方法?列表中的平均timedelta

delta = lambda last, next: (next - last).seconds + (next - last).days * 86400 
total = sum(delta(items[i-1], items[i]) for i in range(1, len(items))) 
average = total/(len(items) - 1) 
+1

在8640的末尾增加一個0會是一個好的開始; – aaronasterling 2010-09-01 10:46:26

+0

爲什麼不增加地球的旋轉速度? ...猜你是對的=) – shinn 2010-09-01 11:02:21

回答

33

順便說一句,如果你有一個timedeltas或日期時間列表,你甚至爲什麼自己做任何數學?

datetimes = [ ... ] 

# subtracting datetimes gives timedeltas 
timedeltas = [datetimes[i-1]-datetimes[i] for i in range(1, len(datetimes))] 

# giving datetime.timedelta(0) as the start value makes sum work on tds 
average_timedelta = sum(timedeltas, datetime.timedelta(0))/len(timedeltas) 
+3

+1因爲OP和我都不知道這是可能性。 datetime廢話比字符串更無聊;) – aaronasterling 2010-09-01 11:37:06

+0

我會用你的方式來計算平均值和aaronasterling的得到的增量。謝謝=) – shinn 2010-09-01 12:50:09

+0

迭代索引並不是很Pythonic。我會用:'[a - b for a,b in zip(datetimes [: - 1],datetimes [1:])]' – abukaj 2017-03-06 14:05:42

3

試試這個:

from itertools import izip 

def average(items): 
    total = sum((next - last).seconds + (next - last).days * 86400 
       for next, last in izip(items[1:], items)) 
    return total/(len(items) - 1) 

在我看來做這樣更具有可讀性。對代碼中較不具數學傾向的讀者的評論可能有助於解釋您如何計算每個三角洲。對於它的價值,一個生成器表達式對我所看到的任何東西的操作碼指令最少(並且我認爲速度最慢)。

# The way in your question compiles to.... 
    3   0 LOAD_CONST    1 (<code object <lambda> at 0xb7760ec0, file 

"scratch.py", line 3>) 
       3 MAKE_FUNCTION   0 
       6 STORE_DEREF    1 (delta) 

    4   9 LOAD_GLOBAL    0 (sum) 
      12 LOAD_CLOSURE    0 (items) 
      15 LOAD_CLOSURE    1 (delta) 
      18 BUILD_TUPLE    2 
      21 LOAD_CONST    2 (<code object <genexpr> at 0xb77c0a40, file "scratch.py", line 4>) 
      24 MAKE_CLOSURE    0 
      27 LOAD_GLOBAL    1 (range) 
      30 LOAD_CONST    3 (1) 
      33 LOAD_GLOBAL    2 (len) 
      36 LOAD_DEREF    0 (items) 
      39 CALL_FUNCTION   1 
      42 CALL_FUNCTION   2 
      45 GET_ITER    
      46 CALL_FUNCTION   1 
      49 CALL_FUNCTION   1 
      52 STORE_FAST    1 (total) 

    5   55 LOAD_FAST    1 (total) 
      58 LOAD_GLOBAL    2 (len) 
      61 LOAD_DEREF    0 (items) 
      64 CALL_FUNCTION   1 
      67 LOAD_CONST    3 (1) 
      70 BINARY_SUBTRACT  
      71 BINARY_DIVIDE  
      72 STORE_FAST    2 (average) 
      75 LOAD_CONST    0 (None) 
      78 RETURN_VALUE   
None 
# 
#doing it with just one generator expression and itertools... 

    4   0 LOAD_GLOBAL    0 (sum) 
       3 LOAD_CONST    1 (<code object <genexpr> at 0xb777eec0, file "scratch.py", line 4>) 
       6 MAKE_FUNCTION   0 

    5   9 LOAD_GLOBAL    1 (izip) 
      12 LOAD_FAST    0 (items) 
      15 LOAD_CONST    2 (1) 
      18 SLICE+1    
      19 LOAD_FAST    0 (items) 
      22 CALL_FUNCTION   2 
      25 GET_ITER    
      26 CALL_FUNCTION   1 
      29 CALL_FUNCTION   1 
      32 STORE_FAST    1 (total) 

    6   35 LOAD_FAST    1 (total) 
      38 LOAD_GLOBAL    2 (len) 
      41 LOAD_FAST    0 (items) 
      44 CALL_FUNCTION   1 
      47 LOAD_CONST    2 (1) 
      50 BINARY_SUBTRACT  
      51 BINARY_DIVIDE  
      52 RETURN_VALUE   
None 

特別是,刪除lambda允許我們避免做一個閉包,構建一個元組並加載兩個閉包。五種功能都被調用。當然,這種對錶演的擔憂有點荒謬,但很高興知道發生了什麼。最重要的是可讀性,我認爲這樣做也得到高分。

+0

是的,那會好很多。謝謝! – shinn 2010-09-01 11:11:47

+0

@shinn,如果你接受THC4k的答案,那麼我可以刪除這一個。 – aaronasterling 2010-09-01 11:49:04

+0

你不應該刪除它。我喜歡用izip的方式。 – shinn 2010-09-01 12:49:01