2012-09-02 25 views
5

आप पाइथन में आसान reduce समारोह जानते हैं। उदाहरण के लिए, आप इसे इस्तेमाल कर सकते हैं (नाटक वहाँ नहीं है में निर्मित sum) तो जैसे एक सूची को योग करने के लिए:पायथन में reducelist: कम करने की तरह लेकिन इंटरमीडिएट परिणामों की सूची दे

reduce(lambda x,y: x+y, [1,2,3,4], 0) 

जो रिटर्न (((0 + 1) +2) +3) + 4 = 10.

अब क्या होगा यदि मैं मध्यवर्ती रकम की एक सूची चाहता था? इस मामले में, [1,3,6,10]

यहां एक बदसूरत समाधान है। क्या कुछ और पाइथनिक है?

def reducelist(f, l, x): 
    out = [x] 
    prev = x 
    for i in l: 
    prev = f(prev, i) 
    out.append(prev) 
    return out 
+0

एफवाईआई, कम से कम हास्केल में इसे * स्कैन * के नाम से जाना जाता है। कम करना कार्यात्मक प्रोग्रामिंग दुनिया में (एक विशिष्ट प्रकार) * गुना * के रूप में भी जाना जाता है। – delnan

+0

धन्यवाद delnan, हाँ, मैं इसे गणित से FoldList के रूप में जानता हूँ। गणित में "सूची" को जोड़कर बताए गए इन कार्यात्मक प्रोग्रामिंग कार्यों में से कई का एक संचय संस्करण है। मैं नीचे दिए गए उत्तर से देखता हूं कि पाइथन 3 में जिसे मैं रेड्यूसेलिस्ट कहता हूं अब जमा() के रूप में उपलब्ध है। – dreeves

उत्तर

8

मेरा पसंदीदा, अगर आप पर्याप्त हाल कर रहे हैं:

Python 3.2.1 (default, Jul 12 2011, 22:22:01) 
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin 
Type "help", "copyright", "credits" or "license" for more information. 
>>> import itertools 
>>> itertools.accumulate([1,2,3,4]) 
<itertools.accumulate object at 0x1006baad0> 
>>> list(itertools.accumulate([1,2,3,4])) 
[1, 3, 6, 10] 

accumulate भी एक समारोह तर्क स्वीकार करता है [और भी अधिक हाल ही में, though-- 3.3]:

>>> list(itertools.accumulate([1,2,3,4], lambda x,y: x+y)) 
[1, 3, 6, 10] 
>>> list(itertools.accumulate([1,2,3,4], lambda x,y: x+y+1)) 
[1, 4, 8, 13] 
+0

आह, अच्छा! हालांकि मेरे लिए यह बहुत हालिया है (मैं पाइथन 2 में हूं) और बहुत विशिष्ट (यह सिर्फ संक्षेप में है, न कि सामान्य रेड्यूसेलिस्ट चीज जिसे मैं ढूंढ रहा हूं)। संपादित करें: आह, यह * सामान्य है, उस वैकल्पिक तर्क के साथ; धन्यवाद! – dreeves

8

आप तो जनरेटर को अपना समाधान कम करें और यह बेहतर प्रोग्रामिंग शैली का पालन करता है। मैं भी एक्स के लिए 0 के एक डिफ़ॉल्ट मान जोड़ना होगा:

def reducelist(f, lst, x=0): 
    prev = x 
    for i in lst: 
    prev = f(prev, i) 
    yield prev 

यही कारण है निश्चित रूप से अधिक pythonic

+0

धन्यवाद! यदि आपको वास्तविक सूची वापस करने की आवश्यकता है तो क्या होगा? क्या हम यहां फ़ंक्शन के भीतर रूपांतरण कर सकते हैं? क्या यह बार-बार जोड़कर सूची बनाने से बेहतर होगा? – dreeves

+0

मैं जनरेटर को 'सूची' फ़ंक्शन के साथ सूची में कनवर्ट करने के लिए फ़ंक्शन के उपयोगकर्ता को छोड़ दूंगा। यदि आप एक ऐसा फ़ंक्शन चाहते हैं जो सीधे एक सूची देता है तो आप एक सहायक कार्य 'reducelist_helper (f, lst, x = 0) बना सकते हैं: वापसी सूची (reducelist (f, lst, x)) ' – halex