2012-02-02 22 views
27

जहां तक ​​मैं समझता हूं, कम फ़ंक्शन एक सूची l और एक फ़ंक्शन f लेता है। फिर, यह सूची के पहले दो तत्वों पर f फ़ंक्शन को कॉल करता है और फिर अगली सूची तत्व और पिछले परिणाम के साथ फ़ंक्शन f को बार-बार कॉल करता है।फ़ंक्शन कैसे काम कम करता है?

तो, मैं निम्नलिखित कार्यों को परिभाषित:

निम्नलिखित समारोह भाज्य गणना करता है।

def fact(n): 
    if n == 0 or n == 1: 
     return 1 
    return fact(n-1) * n 


def reduce_func(x,y): 
    return fact(x) * fact(y) 

lst = [1, 3, 1] 
print reduce(reduce_func, lst) 

अब, यह मुझे ((1! * 3!) * 1!) = 6 नहीं देना चाहिए? लेकिन, इसके बजाय यह 720 देता है। 720 क्यों? ऐसा लगता है कि 6 का फैक्टोरियल भी लगता है। लेकिन, मुझे समझने की जरूरत क्यों है।

क्या कोई बता सकता है कि ऐसा क्यों होता है और एक कार्य-आसपास?

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

+0

सभी को धन्यवाद। मैंने मूर्खतापूर्ण चीज को समझ लिया जो मुझे याद आया। और मैंने जवाब में ऐसा करने का सही तरीका पोस्ट किया है। – Divya

+0

* कम * की गहरी समझ के लिए, नीचे दिखाए गए अपने शुद्ध पायथन समकक्ष देखें। –

उत्तर

0

ठीक, हो गया:

मैं पहली बार उनके factorials के लिए संख्या के नक्शे और फिर गुणा ऑपरेटर के साथ कम कर कॉल करने के लिए की जरूरत है।

तो, यह काम करेगा:

lst_fact = map(fact, lst) 
reduce(operator.mul, lst_fact) 
+0

अच्छा, यह काम की तरह होगा। आपका फैक्टोरियल फ़ंक्शन अभी भी पहले से ही इसके इनपुट के फैक्टोरियल की गणना करता है, इसलिए आपका कमी बस ऐसा नहीं कर रहा है। – Marcin

+0

हां, यह करने का एक तरीका है, और शायद कम से कम "साफ" कार्य को कम करने के अंदर फैक्टोरियल गणना डालने से कुछ अन्य उत्तरों के सुझाव दिए गए हैं - लेकिन कोई भी जो आप चाहते हैं वह करेगा। –

9

आपका फ़ंक्शन पर दोनों तर्क पर कॉल करता है। आप ((1! * 3!)! * 1!) की गणना कर रहे हैं। वैकल्पिक हल केवल केवल दूसरा तर्क पर यह कहते हैं, और Python reduce documentation से reduce() की 1.

7

एक प्रारंभिक मान पास,

को कम करना है (समारोह, अनुक्रम) को फोन करके निर्माण किया एक भी मान देता है (बाइनरी) अनुक्रम के पहले दो आइटमों पर फ़ंक्शन, फिर परिणाम और अगले आइटम पर, और इसी तरह।

तो, आगे बढ़ना। यह पहले दो तत्वों, reduce_func(1, 3) = 1! * 3! = 6 के reduce_func की गणना करता है। फिर, यह परिणाम के reduce_func और अगले आइटम की गणना करता है: reduce_func(6, 1) = 6! * 1! = 720

आप इसे याद करते हैं, जब पहली reduce_func कॉल का परिणाम दूसरे के इनपुट के रूप में पारित किया जाता है, तो यह गुणा से पहले फैक्टोरियलाइज्ड होता है।

0

ठीक है, सब से पहले, अपने reduce_func एक गुना की संरचना नहीं है; यह आपके गुना के वर्णन से मेल नहीं खाता (जो सही है)।

एक गुना की संरचना है: def foldl(func, start, iter): return func(start, foldl(func, next(iter), iter)

अब, अपने fact समारोह दो तत्वों पर काम नहीं करता है - यह सिर्फ भाज्य गणना करता है।

तो, कुल मिलाकर, आप एक गुना का उपयोग नहीं कर रहे हैं, और फैक्टोरियल की उस परिभाषा के साथ, आपको इसकी आवश्यकता नहीं है।

आप, भाज्य के साथ चारों ओर खेलने y-Combinator की जाँच करना चाहते हैं: http://mvanier.livejournal.com/2897.html

आप इस प्रश्न है, जो संचयी अंशों की गणना करने के इसके उपयोग को दर्शाता है करने के लिए अपने जवाब को देखो, परतों के बारे में जानना चाहते हैं :

def myreduce(func, iterable, start=None): 
    it = iter(iterable) 
    if start is None: 
     try: 
      start = next(it) 
     except StopIteration: 
      raise TypeError('reduce() of empty sequence with no initial value') 
    accum_value = start 
    for x in iterable: 
     accum_value = func(accum_value, x) 
    return accum_value 

आप देख सकते हैं कि: creating cumulative percentage from a dictionary of data

25

को समझने के लिए को कम() सबसे आसान तरीका है अपने शुद्ध पायथन बराबर कोड को देखने के लिए है यह केवल आपके reduce_func() के लिए समझ में आता है सबसे दायीं ओर का तर्क को भाज्य लागू करने के लिए:

def fact(n): 
    if n == 0 or n == 1: 
     return 1 
    return fact(n-1) * n 

def reduce_func(x,y): 
    return x * fact(y) 

lst = [1, 3, 1] 
print reduce(reduce_func, lst) 

कि छोटे संशोधन के साथ, कोड का उत्पादन के रूप में आप की उम्मीद :-)

+0

आपने अभी नग्न 'कम' किया है! लेकिन जब 'प्रारंभ = कोई नहीं' 'मिड्रिस ((लैम्बडा एक्स, वाई: एक्स + वाई), [1,2,3,4] नहीं होता है) '11 लौटाता है लेकिन इसमें 10 होना चाहिए; मैंने 'func' – SIslam

+0

के रूप में' sum' लिया है, मुझे लगता है कि सुधार को एक्स के लिए 'x: 1:]: ' – SIslam

+0

के लिए दिखाना चाहिए क्योंकि लूप को' it' 'पर फिर से चालू करना चाहिए,' iterable' नहीं: 'x में इसके लिए:' – vaerek

0

तुम भी लागू कर सकता है कम करने का प्रयोग कर फैक्टरियल।

def factorial(n): 
    return(reduce(lambda x,y:x*y,range(n+1)[1:])) 
38

अन्य उत्तरों महान हैं। इस प्रकार

>>> reduce(lambda x,y: x+y, [47,11,42,13]) 
113 

गणना की जाएगी:: मैं बस एक सचित्र उदाहरण है कि मैं बहुत समझने के लिए reduce() अच्छा लगता है जोड़ देंगे

enter image description here

(Source) (mirror)

+1

वहां हम जाते हैं। धन्यवाद! –

0

कम पैरामीटर # 2

में इटरेटर द्वारा प्रदान किए गए मानों के माध्यम से क्रमशः पैरामीटर # 1 में फ़ंक्शन निष्पादित करता है
print '-------------- Example: Reduce(x + y) --------------' 

def add(x,y): return x+y 
x = 5 
y = 10 

import functools 
tot = functools.reduce(add, range(5, 10)) 
print 'reduce('+str(x)+','+str(y)+')=' ,tot 

def myreduce(a,b): 
    tot = 0 
    for i in range(a,b): 
     tot = tot+i 
     print i,tot 
    print 'myreduce('+str(a)+','+str(b)+')=' ,tot 

myreduce(x,y) 

print '-------------- Example: Reduce(x * y) --------------' 

def add(x,y): return x*y 
x = 5 
y = 10 

import functools 
tot = functools.reduce(add, range(5, 10)) 
print 'reduce('+str(x)+','+str(y)+')=' ,tot 

def myreduce(a,b): 
    tot = 1 
    for i in range(a,b): 
     tot = tot * i 
     print i,tot 
    print 'myreduce('+str(a)+','+str(b)+')=' ,tot 

myreduce(x,y) 
संबंधित मुद्दे