2016-07-01 7 views
14

के लिए डेटाटाइम की सूची की तुलना करें मेरे पास विशिष्ट स्थिति के आधार पर तिथियों के सेट बनाने का कार्य है, उदाहरण के लिए "2 से अधिक" पारित किया जाएगा और मुझे इस महीने की सभी तिथियों का एक सेट बनाना होगा एक दिन> 2. बीमार भी एक प्रारंभ समय और उदाहरण के लिए एक बंद समय हो रही हैडेटाटाइम

greater > 2 less < 9 
start time :10am 
stop time :6 pm 
month:july 
date1: 2016-07-03 10:00, 2016-07-03 16:00 
date2: 2016-07-04 10:00, 2016-07-04 16:00 
date3: 2016-07-05 10:00, 2016-07-05 16:00 
. 
. 
. 
date6: 2016-07-8 10:00, 2016-07-8 16:00 

मैं स्टोर करने के लिए फैसला किया है: 10 am-6pm इस मामले में मैं सभी तिथियों> 2 और हर दिन में यह एक समय 10am से समाप्त होता है और शाम 6 बजे शुरू करने के लिए है का एक सेट का निर्माण करेगा, नीचे एक उदाहरण है निम्नलिखित की तरह एक शब्दकोश में इन तारीखों:

dictD = {'dates_between_2_9':[[2016-07-03 10:00, 2016-07-03 16:00], [2016-07-04 10:00, 2016-07-04 16:00], ....., [2016-07-08 10:00, 2016-07-08 16:00]]} 

मैं dict इस्तेमाल किया क्योंकि मैं ऐसी अनेक शर्तों मैं उनके लिए तारीखों के सेट बनाने की जरूरत है, तो वहाँ उदाहरण dates_between_2_5 से एक और प्रमुख अन्य के लिए किया जाएगा।

दूसरी ओर पर

मैं एक शर्त के आधार पर एक और अनुरोध भी केवल की तरह प्रारंभ समय के साथ तारीखों बनाने के लिए मिलता है निम्नलिखित:

listL = [2016-07-02 14:00,2016-07-03 14:00,2016-07-04 14:00 ... 2016-07-11 14:00] 
:

greater > 1 less than 12 
start time : 2pm 
    date1: 2016-07-02 14:00 
    date2: 2016-07-03 14:00 
    date3: 2016-07-04 14:00 
    . 
    . 
    . 
    date10: 2016-07-11 14:00 

मैं एक सूची में इन तारीखों को स्टोर करने का निर्णय लिया

इसके बाद मैं लिस्टल से प्रत्येक दिनांक की तुलना डिक्टडी से प्रत्येक कुंजी के लिए तारीखों की सूची से करता हूं और यदि लिस्टल की एक तिथि शुरुआत में है, तो समय बंद करें, तो मुझे इसे सूची से हटा देना चाहिए और केवल सूची सूची से तारीखों को वापस करना चाहिए डिक्टडी की तिथियों के साथ ओवरलैप नहीं है, मेरा तर्क अनुवर्ती की तरह है आईएनजी:

for L from ListL: 
    for every key in DictD: 
     for item from DictD[key]: 
      if DictD[key][0] < L < DictD[key][1] # check if item from list overlap with start,stop time from dictionary. 
       ListL.remove(L) # I know I can't remove items from list while iterating so I will probably create a set and store all overlapped items and then subtract this set to set(ListL) to get the difference. 
return ListL 

मेरा प्रश्न है, क्या मैं अपनी आवश्यकताओं को संभालने के लिए एक कुशल डेटा संरचनाओं का उपयोग कर रहा हूं? मुझे लगता है कि मेरा तर्क इतना कुशल नहीं है इसलिए मैं सोच रहा था कि इस समस्या के करीब आने का बेहतर तरीका है या नहीं?

किसी भी मदद की सराहना की जाएगी। अग्रिम धन्यवाद!

+0

एक छोटी ऑफ-विषय सलाह, पूर्णांक स्थिरांक पर अग्रणी शून्य न डालें। पायथन 2 में आपको एक ऐसा मूल्य मिल सकता है जिसका आप इरादा नहीं रखते थे, और पायथन 3 में यह एक त्रुटि उत्पन्न करता है ('00' को छोड़कर)। –

उत्तर

1

सच कहूं बोल मुझे यकीन है कि अगर मैं समझता हूँ कि तुम्हारी समस्या क्या है क्या नहीं हूँ, मैं कुछ इस तरह की कोशिश की:

for date in dateList: 
    for everyrange in dateRange: 
     find=False 
     for i in dateRange[everyrange]: 
      #print('date={date} ,key={everyrange},i={i}'.format(date=date, everyrange=everyrange,i=i)) 
      if i[0] <= date <= i[1]: 
       print(date) 
       find=True 
       break 
      else: 
       print(0) 
     if find: 
      break 
+0

आपके उत्तर के लिए धन्यवाद लेकिन आपका उत्तर ब्रेक के कारण सही जवाब नहीं देता है – tkyass

1

मुझे यकीन है कि मैं पूरी तरह से अपने प्रश्न समझ में आ नहीं कर रहा हूँ, लेकिन मैं आपको पता लगाना चाहते हैं यह सोचते हैं हूँ 'dateLange' सूची से दिनांक जो 'dateRange' dic में किसी विशिष्ट श्रेणी के बीच आते हैं।

मैंने आपके तर्क के आधार पर अपना कोड तैयार करने की कोशिश की। यह काम करना चाहिए:

for date in dateList: 
    for key,value in dateRange.items(): 
     for i in range(0,len(value)): 
      if date>=value[i][0] and date<=value[i][1]: 
       print('The date:',date,'lies between the data points:',value[i][0],'and',value[i][1],'in',key) 

अपने डेटा में, DATERANGE डीआईसी कुंजी ('सीमा') और मूल्यों, जो 2 datetime वस्तुओं की सूची होते हैं। मेरे द्वारा प्रदान किए गए कोड के साथ, डेटरेंज डिक में जितनी चाहें उतनी चाबियां हो सकती हैं, और प्रत्येक कुंजी के मान में आपकी पसंद के अनुसार डेटाटाइम ऑब्जेक्ट की कई सूचियां हो सकती हैं।

+0

आपके उत्तर के लिए धन्यवाद लेकिन आपका उत्तर ठीक उसी तरह की कार्यक्षमता करता है जैसा मैंने प्रदान किया है कोड – tkyass

1

मैंने आपकी मांग के आधार पर इस उदाहरण की कोशिश की और अच्छी तरह से काम किया =)। एल्गोरिदम आपके द्वारा पोस्ट किए गए एक जैसा ही है, केवल एल्गोरिदम के अंत में ही विचलन होता है। मैं आपके द्वारा बनाई गई फ़ंक्शन में लौटने के लिए एक नई सूची बनाना चुनता हूं।

कोड यह रहा:

list_1 = ['a 1', 'a 2', 'a 3', 'a 4', 'a 5', 'b 1', 'b 2', 'b 3', 'b 4', 'b 5', 'c 1', 'c 2', 'c 3', 'c 4', 'c 5'] 
dict = {'example_between_2_5': [['a 3', 'a 4'], ['b 3', 'b 4'], ['c 3', 'c 4']]} 
new_list = [] 


# Defining the number of repetitions based on how many 'lists' inside the dict you have. 
for x in range(0, len(dict['example_between_2_5'])): 
    dict_list_elements = dict['example_between_2_5'][x] 
    # Defining the number of repetitions based on the elements inside the list of the dict. 
    for y in range(0, len(dict_list_elements)): 
     #Picking the element 
     dict_list_element = dict_list_elements[y] 
     for z in range(0, len(list_1)): 
      #Comparing to all elements in list_1 
      if dict_list_element == list_1[z]: 
       #The element will be append if doesn't exist in the new list 
       if list_1[z] not in new_list: 
        new_list.append(list_1[z]) 

#Printing the result just to check if it worked. 
print("list_1: ", list_1) 
print("New_list: ", new_list) 

आशा है कि यह मदद करता है =)

5

ऐसा लगता है कि आप अपने एल्गोरिथ्म अनुकूलन करने के लिए कोशिश कर रहे हैं। इस आकार के आंकड़ों के साथ ईमानदार होने के लिए, शायद यह आवश्यक नहीं है। हालांकि, यदि आप रुचि रखते हैं, तो सदस्यता के लिए जांच करते समय पाइथन में sets are faster than lists अंगूठे का सामान्य नियम है।

इस मामले में, यह स्पष्ट नहीं है कि आपके सेट क्या हो सकते हैं। मैंने माना है कि आपके पास ग्रैन्युलरिटी का एक मिनट-स्तर है, लेकिन आप कम (अधिक मेमोरी के लिए) जा सकते हैं या वास्तव में बड़े ग्रॅन्युलरिटी के लिए जाकर अधिभोग और प्रदर्शन में सुधार कर सकते हैं - उदा। घंटे। इस कोड से पता चलता भी अपेक्षाकृत बड़े सेट कम से कम 5x तेजी से हो सकता है (और जब आपका डेटा सेट की तुलना में एक छोटे से सरल नज़र डालें): रिकॉर्ड के लिए

from copy import copy 
from datetime import datetime, timedelta 
from timeit import timeit 
import time 

def make_range(start, open, close, days): 
    result = [] 
    base_start = start + open 
    base_close = start + close 
    while days > 0: 
     result.append([base_start, base_close]) 
     base_start += timedelta(days=1) 
     base_close += timedelta(days=1) 
     days -= 1 
    return result 

def make_range2(start, open, close, days): 
    result = set() 
    base_start = start + open 
    base_close = start + close 
    while days > 0: 
     now = base_start 
     while now <= base_close: 
      result.add(now) 
      now += timedelta(minutes=1) 
     base_start += timedelta(days=1) 
     base_close += timedelta(days=1) 
     days -= 1 
    return result 

dateRange = { 
    'range1': make_range(datetime(2016, 7, 3, 0, 0), 
         timedelta(hours=10), 
         timedelta(hours=18), 
         6), 
} 

dateRange2 = { 
    'range1': make_range2(datetime(2016, 7, 3, 0, 0), 
          timedelta(hours=10), 
          timedelta(hours=18), 
          6), 
} 

dateList = [ 
    datetime(2016, 7, 2, 14, 0), 
    datetime(2016, 7, 3, 14, 0), 
    datetime(2016, 7, 4, 14, 0), 
    datetime(2016, 7, 5, 14, 0), 
    datetime(2016, 7, 6, 14, 0), 
    datetime(2016, 7, 7, 14, 0), 
    datetime(2016, 7, 8, 14, 0), 
    datetime(2016, 7, 9, 14, 0), 
    datetime(2016, 7, 10, 14, 0), 
    datetime(2016, 7, 11, 14, 0) 
] 

dateSet = set(dateList) 

def f1(): 
    result = copy(dateList) 
    for a in dateList: 
     for b in dateRange: 
      for i in dateRange[b]: 
       if i[0] <= a <= i[1]: 
        result.remove(a) 
    return result 

def f2(): 
    result = copy(dateSet) 
    for b in dateRange2: 
     result = result.difference(dateRange2[b]) 
    return result 

print(f1()) 
print(timeit("f1()", "from __main__ import f1", number=100000)) 

print(f2()) 
print(timeit("f2()", "from __main__ import f2", number=100000)) 

, परिणाम इस प्रकार हैं:

[datetime.datetime(2016, 7, 2, 14, 0), datetime.datetime(2016, 7, 9, 14, 0), datetime.datetime(2016, 7, 10, 14, 0), datetime.datetime(2016, 7, 11, 14, 0)] 
1.922587754837455 

{datetime.datetime(2016, 7, 2, 14, 0), datetime.datetime(2016, 7, 9, 14, 0), datetime.datetime(2016, 7, 10, 14, 0), datetime.datetime(2016, 7, 11, 14, 0)} 
0.30558400587733225 

आप एक सूची में dict dateRange को भी परिवर्तित कर सकते हैं, लेकिन केवल 1 या 2 सदस्यों के साथ, प्रदर्शन में कोई वास्तविक अंतर करने की संभावना नहीं है। हालांकि, यह अधिक तार्किक अर्थ बनाता है, क्योंकि आप वास्तव में किसी विशेष कुंजी मान को देखने के लिए निर्देश का उपयोग नहीं कर रहे हैं - आप बस सभी मानों के माध्यम से पुनरावृत्त कर रहे हैं।

+0

मुझे आपका उत्तर पसंद है, लेकिन मैं उस हिस्से के बारे में सोच रहा हूं आप हर बार एक रेंज बनाते हैं जिसे हम तुलना करना चाहते हैं, क्या यह प्रदर्शन को प्रभावित करता है? – tkyass

+0

@tkyass मुझे देखने के लिए एक त्वरित खेल हो सकता है ... स्पष्ट होने के लिए - क्या आप उस रेखा का मतलब है जहां मैं डेटसेट/डेटलिस्ट को डुप्लिकेट करता हूं (आप किस फ़ंक्शन पर कॉल करते हैं)? –

1

मैं अभी भी बिल्कुल निश्चित नहीं हूं कि आप क्या हासिल करने की कोशिश कर रहे हैं लेकिन कृपया इस कोड को देखें और मुझे बताएं कि यह वही है जो आप चाहते हैं।

महीने इनपुट करने का विकल्प भी है।

सूची 1 नाम की सूची आपके शब्दकोश dictD के बराबर है।

सूची 2 नाम की सूची आपकी सूची सूची एल के बराबर है। इसमें केवल वे तिथियां हैं जो सूची 1 (dictD) में उन लोगों के साथ ओवरलैप नहीं होती हैं।

यहां कोड है।

from datetime import datetime 

#Converts 12-hour(am/pm) to 24-hour format 
def get_time(time): 
    digit = int(time[0:-2]) 
    if time[-2:] == 'am': 
     return digit 

    else: 
     return digit+12 


month_number = { 
    'january':1, 'february':2, 'march':3, 'april':4, 'may':5, 'june':6, 
    'july':7, 'august':8, 'september':9, 'october':10, 'november':11, 'december':12 
} 

gt1 = input('Enter first set\ngreater > ') 
lt1 = input('less < ') 

start1 = raw_input('start time: ') 
stop1 = raw_input('stop time: ') 

month1 = raw_input('month: ') 


gt2 = input('\nEnter second set\ngreater > ') 
lt2 = input('less < ') 

start2 = raw_input('start time: ') 

month2 = raw_input('month: ') 

list1 = [] 
list2 = [] 

today = datetime.today() 

start1 = get_time(start1) 
stop1 = get_time(stop1) 
start2 = get_time(start2) 

key = 'dates_between_%s_%s'%(gt1, gt2) 

for i in range(gt1+1, lt1): 
    list1.append(
      [ 
      datetime(today.year, month_number[month1], i, start1, 0).strftime("%Y-%m-%d %H:%M"), 
      datetime(today.year, month_number[month1], i, stop1, 0).strftime("%Y-%m-%d %H:%M") 
      ] 
     ) 

for i in range(gt2+1, lt2): 
    if (month1 == month2) and (gt1 < i < lt1) and (start1 < start2 < stop1): 
     pass 
    else: 
     list2.append(datetime(today.year, month_number[month2], i, start2, 0).strftime("%Y-%m-%d %H:%M")) 

print 'List1:\n',list1 
print '\nList2:\n',list2 
संबंधित मुद्दे