2012-01-24 10 views
10

मैं datetimes का एक क्रमबद्ध सूची मिल गया है: (दिन के अंतराल के साथ)स्प्लिट सूची

list_of_dts = [ 
       datetime.datetime(2012,1,1,0,0,0), 
       datetime.datetime(2012,1,1,1,0,0), 
       datetime.datetime(2012,1,2,0,0,0), 
       datetime.datetime(2012,1,3,0,0,0), 
       datetime.datetime(2012,1,5,0,0,0), 
       ] 

और मैं प्रत्येक दिन के लिए एक सूची में उन्हें विभाजित करने के लिए करना चाहते हैं:

result = [ 
      [datetime.datetime(2012,1,1,0,0,0), datetime.datetime(2012,1,1,1,0,0)], 
      [datetime.datetime(2012,1,2,0,0,0)], 
      [datetime.datetime(2012,1,3,0,0,0)], 
      [], # Empty list for no datetimes on day 
      [datetime.datetime(2012,1,5,0,0,0)] 
     ] 

एल्गोरिदमिक रूप से, कम से कम ओ (एन) प्राप्त करना संभव होना चाहिए।

शायद निम्नलिखित की तरह कुछ: (यह स्पष्ट रूप से प्रबंधन नहीं करती है याद दिनों, और पिछले डीटी चला जाता है, लेकिन यह एक शुरुआत है)

def dt_to_d(list_of_dts): 
    result = [] 
    start_dt = list_of_dts[0] 
    day = [start_dt] 
    for i, dt in enumerate(list_of_dts[1:]): 
     previous = start_dt if i == 0 else list_of_dts[i-1] 
     if dt.day > previous.day or dt.month > previous.month or dt.year > previous.year: 
      # split to new sub-list 
      result.append(day) 
      day = [] 
      # Loop for each day gap? 
     day.append(dt) 
    return result 

विचार?

+1

datetime_value साथ सूचियों का एक dict का उपयोग की एक सूची है कुंजी के रूप में .date()। –

उत्तर

12

जाना सबसे आसान तरीका है एक ही दिन में न्यूनतम से उच्चतम दिन खत्म पाश गिरने और फिर समूह प्रविष्टियों को dict.setdefault उपयोग करने के लिए है:

>>> import datetime 
>>> list_of_dts = [ 
       datetime.datetime(2012,1,1,0,0,0), 
       datetime.datetime(2012,1,1,1,0,0), 
       datetime.datetime(2012,1,2,0,0,0), 
       datetime.datetime(2012,1,3,0,0,0), 
       datetime.datetime(2012,1,5,0,0,0), 
       ] 

>>> days = {} 
>>> for dt in list_of_dts: 
     days.setdefault(dt.toordinal(), []).append(dt) 

>>> [days.get(day, []) for day in range(min(days), max(days)+1)] 
[[datetime.datetime(2012, 1, 1, 0, 0), datetime.datetime(2012, 1, 1, 1, 0)], 
[datetime.datetime(2012, 1, 2, 0, 0)], 
[datetime.datetime(2012, 1, 3, 0, 0)], 
[], 
[datetime.datetime(2012, 1, 5, 0, 0)]] 

इस तरह के समूहों बनाने के लिए एक और दृष्टिकोण itertools.groupby है। यह इस तरह का काम करने के लिए डिज़ाइन किया गया है, लेकिन यह एक तरह से लापता दिनों के लिए पूर्ति में एक खाली सूची प्रदान नहीं करता है:

>>> import itertools 
>>> [list(group) for k, group in itertools.groupby(list_of_dts, 
                key=datetime.datetime.toordinal)] 
[[datetime.datetime(2012, 1, 1, 0, 0), datetime.datetime(2012, 1, 1, 1, 0)], 
[datetime.datetime(2012, 1, 2, 0, 0)], 
[datetime.datetime(2012, 1, 3, 0, 0)], 
[datetime.datetime(2012, 1, 5, 0, 0)]] 
+1

setdefault और सौहार्दपूर्ण मेरे जवाब पर अच्छे सुधार हैं। :-) –

+2

'setdefault' से भी सरल' डिफ़ॉल्ट डिफॉल्ट '('संग्रह' से) हो सकता है। – Amber

+0

सुंदर - धन्यवाद! मैं अपनी 'list_of_dts' के रूप में एक ही समय में अपनी 'दिन' सूची उत्पन्न कर सकता हूं, इसलिए यह बहुत ही कुशल होगा। –

4

आप itertools.groupby का उपयोग आसानी से समस्याओं के इस प्रकार संभाल करने के लिए कर सकते हैं:

import datetime 
import itertools 

list_of_dts = [ 
     datetime.datetime(2012,1,1,0,0,0), 
     datetime.datetime(2012,1,1,1,0,0), 
     datetime.datetime(2012,1,2,0,0,0), 
     datetime.datetime(2012,1,3,0,0,0), 
     datetime.datetime(2012,1,5,0,0,0), 
     ] 

print [list(g) for k, g in itertools.groupby(list_of_dts, key=lambda d: d.date())] 
+0

जानना अच्छा है - धन्यवाद! हालांकि, गायब दिनों के लिए खाली सूची की आवश्यकता को संभाल नहीं आता है। –

+0

@Alex Ahh, वास्तव में, मैं किसी भी तरह से उस बिंदु को नोटिस करने में विफल रहा। – qiao

1

भरने अंतराल:

date_dict = {} 
for date_value in list_of_dates: 
    if date_dict.has_key(date_value.date()): 
     date_dict[date_value.date()].append(date_value) 
    else: 
     date_dict[date_value.date()] = [ date_value ] 
sorted_dates = sorted(date_dict.keys()) 
date = sorted_dates[0] 
while date <= sorted_dates[-1]: 
    print date_dict.get(date, []) 
    date += datetime.timedelta(1) 

परिणाम:

[datetime.datetime(2012, 1, 1, 0, 0), datetime.datetime(2012, 1, 1, 1, 0)] 
[datetime.datetime(2012, 1, 2, 0, 0)] 
[datetime.datetime(2012, 1, 3, 0, 0)] 
[] 
[datetime.datetime(2012, 1, 5, 0, 0)] 

इस समाधान को मूल डेटाटाइम सूची को सॉर्ट करने की आवश्यकता नहीं है।

1
list_of_dts = [ 
      datetime.datetime(2012,1,1,0,0,0), 
      datetime.datetime(2012,1,1,1,0,0), 
      datetime.datetime(2012,1,2,0,0,0), 
      datetime.datetime(2012,1,3,0,0,0), 
      datetime.datetime(2012,1,5,0,0,0), 
      ] 

groupedByDay={} 
for date in list_of_dts: 
    if date.date() in groupedByDay: 
     groupedByDay[date.date()].append(date) 
    else: 
     groupedByDay[date.date()]=[date] 

अब आपके पास एक शब्दकोश है, जहां तारीख कुंजी है और मान समान तिथियों की एक सूची है।

और आप एक सूची होने पर सेट कर रहे हैं, तो बजाय

result = groupedByDay.values() 
result.sort() 

अब परिणाम सूचियों, जहां एक ही दिन के साथ सभी तिथियों साथ रखे जाते हैं

+2

'date.date() समूहबद्ध में ByDay.keys() 'ओ (एन) है। क्या आप इसे groupedByDay' में 'date.date() से बदल सकते हैं? यह ओ (1) है। – reclosedev

+0

किया गया। पारितोषिक के लिए धन्यवाद। मैंने अभी हाल ही में पायथन उठाया है .. हर दिन कुछ नया सीखो। – Lex

संबंधित मुद्दे