मैं डेटटाइम को एक ताना कुंजी के रूप में उपयोग करने में समस्या में भाग रहा हूं। मेरा लक्ष्य एक डेटा स्रोत से जानकारी लाना है जिसमें डेटाटाइम शामिल है, और फिर एक शब्दकोश में देखें और उन कुंजियों के लिए सभी मान लौटाएं जो इनपुट डेटटाइम के 2 दिनों + के भीतर हैं।

उदाहरण के लिए, मेरा इनपुट होगा: datetime.datetime(2018, 9, 20, 12, 48)

संदर्भ के लिए मेरा शब्दकोश होगा: example = {datetime.datetime(2018, 9, 20, 14, 43):'A', datetime.datetime(2018, 9, 18, 19, 41):'B', datetime.datetime(2018, 9, 15, 9, 12):'C'}

उस स्थिति में, मैं वापस आऊंगा: A, B

मैंने डिक्शनरी को छाँटने पर विचार किया है और फिर शायद विषम-संख्या वाली तारीखों के लिए इंडेक्स का एक डिक्शनरी बनाना, फिर मेरी इनपुट डेट लेना, इनपुट डेट की बेस डेट + - 2 का पता लगाना, इंडेक्स डिक्टेट का संदर्भ देना, और फिर उन इंडेक्स का उपयोग करना केवल इंडेक्स के बीच संदर्भ के माध्यम से लूप करें और वहां मौजूद सभी मानों को वापस कर दें।

मेरा मुख्य मुद्दा यह है कि मैं भविष्यवाणी नहीं कर सकता कि ताना डेटाटाइम क्या होगा या इनपुट डेटाटाइम्स इसलिए मैं निश्चित नहीं हूं कि क्या मैं चाबियों की अनुक्रमणिका के माध्यम से लूपिंग के अलावा किसी अन्य नियम में चाबियों की एक श्रृंखला के लिए मान वापस कर सकता हूं क्रमबद्ध क्रम में। देखने के लिए चाबियों की संख्या के कारण सभी चाबियों के लिए लूप करना यहां कुशल नहीं है - मैं पहले से ही जितना संभव हो उतना कम करके और केवल न्यूनतम मात्रा में संदर्भ डेटा लाकर इस सूची को कम कर रहा हूं।

एक अन्य वस्तु यह है कि मेरे इनपुट देखने के लिए १००,००० डेटाटाइम होंगे, जिनमें से कई एक दूसरे से मिनट, सेकंड या घंटे दूर होंगे, इसलिए लुकअप की संख्या को कम करना और लूपिंग के लिए रनटाइम को नीचे रखना आवश्यक होगा .

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

1
MyNameIsCaleb 25 सितंबर 2018, 10:47

1 उत्तर

सबसे बढ़िया उत्तर
  • सबसे पहले, डिक्शनरी डेट्स को सॉर्ट करें और डिक्शनरी को सॉर्ट किए गए टुपल्स की सूची में बदलें:

    dic_dates = {
        datetime.datetime(2018, 9, 20, 14, 43):'A',
        datetime.datetime(2018, 9, 18, 12, 41):'B',
        datetime.datetime(2018, 9, 15, 9, 12):'C'
    }
    
    sorted_dates = sorted(dic_dates.items())
    
  • फिर उस सूची के अंदर अपनी तिथि की स्थिति खोजने के लिए द्विभाजित का उपयोग करें:

    dat = datetime.datetime(2018, 9, 20, 12, 48)
    insert_index = bisect.bisect_left(sorted_dates, (dat,None))
    
  • इस स्थिति से बाईं ओर देखें और जैसे ही कोई तत्व स्थिति को सत्यापित नहीं करता है, ब्रेक करें, फिर स्थिति से दाईं ओर शुरू करके ऐसा ही करें। (आप अपनी शर्तों का उपयोग कर सकते हैं क्योंकि मैंने पाया कि यह आपके उदाहरण में काफी अस्पष्ट था - + -2 दिन 'बी' आईएमओ का चयन नहीं करना चाहिए लेकिन यह बात नहीं है)

    if insert_index:
    #if insert_index = 0, do not loop on left side
        dat_min = dat - datetime.timedelta(days=2)
        for d in sorted_dates[insert_index-1::-1]:
            if d[0] > dat_min:
                print(d[1])
            else:
                break
    
    dat_max = dat + datetime.timedelta(days=2)
    for d in sorted_dates[insert_index:]:
        if d[0] < dat_max:
            print(d[1])
        else:
            break
    

संपादित करें

Bisct_left कार्यान्वयन का एक उदाहरण:

def bisect_left(l, e, start = 0):
    if not l:
        return start
    pos = int(len(l)/2)
    if l[pos] < e and (pos+1 >= len(l) or l[pos+1] > e):
        return start + pos + 1
    elif l[pos] >= e:
        return bisect_left(l[:pos], e, start)
    else:
        return bisect_left(l[pos:], e, start+pos)

मैं आपको द्विभाजित का उपयोग करने की दृढ़ता से सलाह देता हूं क्योंकि यह तेज और अधिक विश्वसनीय होगा।

1
Corentin Limier 25 सितंबर 2018, 15:14