2009-07-29 14 views
11

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

if p <= 100: 
    return 0 
elif p > 100 and p <= 300: 
    return 1 
elif p > 300 and p <= 500: 
    return 2 
elif p > 500 and p <= 800: 
    return 3 
elif p > 800 and p <= 1000: 
    return 4 
elif p > 1000: 
    return 5 

IMO काफी भयानक है, और कहा कि दोनों के अंतराल में अभाव है और वापसी मान हार्डकोडेड कर रहे हैं। किसी भी डेटा संरचना का कोई भी उपयोग निश्चित रूप से संभव है।

उत्तर

35
import bisect 
bisect.bisect_left([100,300,500,800,1000], p) 
+0

+1 मुझे यह पसंद है। आप हर दिन कुछ नया सीखते हैं। – kjfletch

+0

+1: अविश्वसनीय! –

+1

वास्तव में प्रभावशाली। सुपर साफ, और मैं भी बहुत तेज़ विश्वास करता हूँ। यदि किसी को गैर-प्राकृतिक ऑर्डरिंग या बदले में कुछ और की आवश्यकता होती है, तो इसे आसानी से बढ़ाया जा सकता है, जैसे स्ट्रिंग: आयात bisect n = bisect।bisect_left ([100,300,500,800,1000], पी) ए = ["अनुपस्थित", "कम", "औसत", "उच्च", "बहुत ऊंचा", "चरम"] एक [एन] – Agos

0

की तर्ज पर की कोशिश कुछ:

d = {(None,100): 0, 
    (100,200): 1, 
    ... 
    (1000, None): 5} 
value = 300 # example value 
for k,v in d.items(): 
    if (k[0] is None or value > k[0]) and (k[1] is None or value <= k[1]): 
     return v 
3

आप इस पर एक ले कोशिश कर सकते:

def check_mapping(p): 
    mapping = [(100, 0), (300, 1), (500, 2)] # Add all your values and returns here 

    for check, value in mapping: 
     if p <= check: 
      return value 

print check_mapping(12) 
print check_mapping(101) 
print check_mapping(303) 

पैदा करता है:

0 
1 
2 

हमेशा की तरह अजगर में, वहाँ हो जाएगा इसे करने के लिए कोई बेहतर तरीका है।

+0

पी> 1000 के मामले पर विचार नहीं करता है! – stefanw

+0

यही कारण है कि मैंने निर्दिष्ट किया: "आप इस पर लेने का प्रयास कर सकते हैं" – kjfletch

+0

वह अंतिम वाक्य विडंबना है, जो कि कुछ करने के लिए अधिमानतः केवल एक स्पष्ट तरीका होने के पाइथन दर्शन पर विचार करता है। – sykora

0
def which_interval(endpoints, number): 
    for n, endpoint in enumerate(endpoints): 
     if number <= endpoint: 
      return n 
     previous = endpoint 
    return n + 1 

endpoints में एक सूची के रूप में अपने अंतिम बिंदु दर्रा, इस तरह:

which_interval([100, 300, 500, 800, 1000], 5) 

संपादित करें:

ऊपर एक रेखीय खोज है। ग्लेन मेनार्ड के जवाब में बेहतर प्रदर्शन होगा, क्योंकि यह एक बिसेक्शन एल्गोरिदम का उपयोग करता है।

+0

"पिछले" कांपर खोना; यह काफी अनावश्यक है। –

+0

हाँ, आप सही हैं, मुझे लगता है कि मूल कोड "प्रेरित" मुझे इसका उपयोग करने के लिए। बीटीडब्ल्यू, अनिवार्य रूप से आपका उपयोग कुछ लोगों के लिए थोड़ा सा गड़बड़ हो सकता है। – Steef

+0

@ स्टेफ: आप एक विनम्र सुझाव पर विचार करना चाह सकते हैं कि आप अपने अवकाश पर अपने उत्तर को संशोधित कर सकते हैं, ध्यान दें कि ** आपके उत्तर में अभी भी कोड की अनावश्यक रेखा शामिल है **, और समय की पूर्णता में, इसे उत्पादित करें। –

0

एक और तरीका है ...

def which(lst, p): 
    return len([1 for el in lst if p > el]) 

lst = [100, 300, 500, 800, 1000] 
which(lst, 2) 
which(lst, 101) 
which(lst, 1001) 
3

यह वास्तव में काफी भयानक है। बिना एक आवश्यकता नहीं hardcoding है, इसे इस तरह लिखा जाना चाहिए किया गया है:

if p <= 100: 
    return 0 
elif p <= 300: 
    return 1 
elif p <= 500: 
    return 2 
elif p <= 800: 
    return 3 
elif p <= 1000: 
    return 4 
else: 
    return 5 

यहाँ कोई hardcodings आवश्यकता को पूरा के साथ एक देखने समारोह, दोनों रैखिक बनाने और द्विआधारी खोज का उपयोग कर, के उदाहरण हैं, और एक जोड़ी दो टेबल पर सैनिटी चेक की:

def make_linear_lookup(keys, values): 
    assert sorted(keys) == keys 
    assert len(values) == len(keys) + 1 
    def f(query): 
     return values[sum(1 for key in keys if query > key)] 
    return f 

import bisect 
def make_bisect_lookup(keys, values): 
    assert sorted(keys) == keys 
    assert len(values) == len(keys) + 1 
    def f(query): 
     return values[bisect.bisect_left(keys, query)] 
    return f 
+0

मुझे यह बेहतर पसंद है जिसकी अधिक सामान्यता/गैर-हार्डकोडेड रूप की वजह से सबसे अधिक वोट हैं और क्योंकि यह अधिक गहराई से है। – JAB

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