2013-08-26 10 views
7

निम्न कोड में:अजगर सूची टुकड़ा करने की क्रिया दक्षता

def listSum(alist): 
    """Get sum of numbers in a list recursively.""" 
    sum = 0 
    if len(alist) == 1: 
     return alist[0] 
    else: 
     return alist[0] + listSum(alist[1:]) 
    return sum 

हर बार बनाया जब मैं listSum(alist[1:]) कर एक नई सूची है?

यदि हां, तो यह अनुशंसित तरीका है या क्या मैं कुछ और कुशल कर सकता हूं? (नहीं विशेष समारोह के लिए -इस एक उदाहरण के रूप में कार्य करता है, बल्कि जब मैं सामान्य रूप में एक सूची के एक विशिष्ट भाग पर कार्रवाई करना चाहते हैं।)

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

क्षमा करें यदि मैं किसी को भी उलझन में, मैं नहीं कर रहा हूँ एक कुशल sum कार्यान्वयन में रूचि रखते हुए, इसने स्लाइसिंग का उपयोग करने के लिए एक उदाहरण के रूप में कार्य किया।

उत्तर

5

हां, यह हर बार एक नई सूची बनाता है। यदि आप एक पुनरावृत्त उपयोग करने से दूर हो सकते हैं, तो आप itertools.islice का उपयोग कर सकते हैं, या iter(list) juggle (यदि आपको केवल शुरुआत में कुछ आइटम छोड़ने की आवश्यकता है) का उपयोग कर सकते हैं। लेकिन यह गन्दा हो जाता है जब आपको यह निर्धारित करने की आवश्यकता होती है कि तर्क खाली है या केवल एक तत्व है - आपको try का उपयोग करना होगा और StopIteration पकड़ना होगा। संपादित करें: आप एक अतिरिक्त तर्क भी जोड़ सकते हैं जो यह निर्धारित करता है कि कहां से शुरू करना है। @ मार्कडियन के संस्करण के विपरीत, आपको इसे कॉलर को बोझ न करने और बाहरी से गुजरने वाली गलत अनुक्रमणिका से बग से बचने के लिए एक डिफ़ॉल्ट तर्क देना चाहिए।

इस तरह की स्थिति में नहीं जाना अक्सर बेहतर होता है - या तो अपना कोड लिखें जैसे कि आप for पुनरावृत्ति के साथ सौदा कर सकते हैं (पढ़ें: उस तरह रिकर्सन का उपयोग न करें)। वैकल्पिक रूप से, यदि टुकड़ा काफी छोटा है (संभवतः क्योंकि पूरी तरह से सूची छोटी है), बुलेट और स्लाइस को काट लें - यह आसान है, और स्लाइसिंग रैखिक समय है, निरंतर कारक वास्तव में छोटा है।

+0

तो, एक खिलौना उदाहरण के रूप में मानते हुए कि मेरे पास संख्याओं की काफी बड़ी सूची है, और मैं उनमें से आधे से जोड़ना चाहता हूं। क्या मेरी सूची में 'संख्या के लिए कुछ है [मध्य:]: संख्या + = 2' स्वीकार्य है? (या इसे वास्तव में बड़ी सूची को टुकड़ा करने के लिए एक अच्छा अभ्यास नहीं माना जाता है?) –

+1

@i_am_finally_learning_python उस उदाहरण को छोड़कर उस उदाहरण को काम नहीं करता है - 'mylist' की सामग्री को परिवर्तित नहीं करता है (और इसे करने का सबसे आसान तरीका शामिल है कुछ भी टुकड़ा नहीं) - यह निर्भर करता है। स्लाइसिंग में बड़ा प्लस होता है जो वैकल्पिक रूप से सरल और सुंदर होता है। लेकिन "काफी बड़ा" क्या है, यह कोड कितनी बार निष्पादित करता है, और अन्य कारकों के आधार पर, यह कष्टप्रद धीमा हो सकता है और कम पठनीय टुकड़ा-कम विकल्प इसके लायक है। सामान्य रूप से कहना मुश्किल है। – delnan

+0

ओह लेकिन निश्चित रूप से, मुझे लगता है कि मुझे उन पाइथन के साथ लूप के लिए अतिरंजित मिला !! इससे कुछ सामान साफ ​​हो गया, धन्यवाद। –

2

मैं कुछ विकल्पों के बारे में सोच सकते हैं:

  1. उपयोग इस विशेष मामले
  2. तुम सच में प्रत्यावर्तन (किसी कारण के लिए) की जरूरत है के लिए builtin समारोह योग, समारोह कॉल करने के लिए एक ही सूची में पास और भी

    def f_sum(alist, idx=0): 
        if idx >= len(alist): 
         return 0 
        return alist[idx] + f_sum(alist, idx + 1) 
    
    
    f_sum([1, 2, 3, 4]) 
    a = range(5) 
    f_sum(a) 
    
    : वर्तमान तत्व के सूचकांक है, तो आप सूची (जो नई सूची बनाता है)

विकल्प इस तरह 2 काम करता है स्लाइस की जरूरत नहीं है

0

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

def helper(l, s, i): 
    if len(l) == 0: 
     return 0 
    elif i < len(l) - 1: 
     return helper(l, s + l[i], i + 1) 
    else: 
     return s + l[i] 


def listSum(l): 
    return helper(l, 0, 0) 
+0

सिवाय इसके कि कोई भी प्रमुख पायथन कार्यान्वयन नहीं करता है, या संभवतया कभी भी प्रदर्शन करेगा, पूंछ रिकर्सन उन्मूलन। साथ ही, उन दो कार्यों को डिफ़ॉल्ट तर्कों का उपयोग करके एक में विलय किया जा सकता है। – delnan

+0

ठीक है, मैं अपने संपादन में इसका एक नोट बनाउंगा। – Joohwan

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