2012-05-31 9 views
72

चलें कहते हैं कि हम एक समारोह के रूपमैप फ़ंक्शन के लिए कई तर्क कैसे करें जहां कोई अजगर में समान रहता है?

def add(x, y): 
    return x + y 

हम एक सरणी

map(add, [1, 2, 3], 2) 

अर्थ विज्ञान मैं सरणी के प्रत्येक तत्व के लिए 2 जोड़ना चाहते हैं के लिए नक्शा समारोह लागू करना चाहते हैं इस प्रकार जोड़ने की है। लेकिन map फ़ंक्शन को तीसरे तर्क में भी एक सूची की आवश्यकता है।

नोट: मैं सादगी के लिए अतिरिक्त उदाहरण डाल रहा हूं। मेरा मूल कार्य बहुत जटिल है। और निश्चित रूप से y के डिफ़ॉल्ट मान को सेट फ़ंक्शन में सेट करने का विकल्प प्रश्न से बाहर है क्योंकि यह प्रत्येक कॉल के लिए बदला जाएगा।

+8

यह लिस्प में बिल्कुल वैसा ही है: 'नक्शा (जोड़ें, [1,2,3], [2] * 3)' सामान्य 'मानचित्र' में पहले कार्य के रूप में कार्य करता है, और यदि यह कार्य ** के ** तर्क लेता है, आपको ** के ** के साथ अनुवर्ती करना होगा: 'addTriple (ए, बी, सी) -> मानचित्र (addTriple, [...], [...], [। ..]) ' – watashiSHUN

उत्तर

105

एक विकल्प एक सूची समझ है:

[x + 2 for x in [1, 2, 3]] 

तुम सच में, वास्तव में, वास्तव मेंmap उपयोग करना चाहते हैं है, यह पहला तर्क के रूप में एक गुमनाम समारोह देना

[add(x, 2) for x in [1, 2, 3]] 

अधिक विकल्प:

a = [1, 2, 3] 

import functools 
map(functools.partial(add, y=2), a) 

import itertools 
map(add, a, itertools.repeat(2, len(a))) 
+1

yup, लेकिन मानचित्र फ़ंक्शन की तुलना में यह कितनी तेज़ है? – Shan

+0

@Shan: बहुत समान, विशेष रूप से यदि 'add() 'एक गैर-तुच्छ कार्य है –

+0

@Shan: सूची की समझ मेरे बॉक्स पर लगभग 15% तेज है। –

30

एक सूची समझ का उपयोग करें।

map(lambda x: x + 2, [1,2,3]) 
12

यदि आपके पास यह उपलब्ध है, तो मैं numpy का उपयोग करने पर विचार करता हूं। यह आपरेशन के इन प्रकार के लिए बहुत तेजी से है:

>>> import numpy 
>>> numpy.array([1,2,3]) + 2 
array([3, 4, 5]) 

यह मानते हुए है अपने वास्तविक आवेदन गणितीय क्रियाओं कर रहा है (कि vectorized जा सकता है)।

+4

यह माना जा रहा है कि आपका असली एप्लिकेशन गणितीय परिचालन कर रहा है * जिसे NumPy का उपयोग करके वेक्टरिज्ड किया जा सकता है। * –

+0

हाँ, अच्छी पकड़, अद्यतन – jterrace

8

यदि आपको वास्तव में वास्तव में मानचित्र फ़ंक्शन का उपयोग करने की आवश्यकता है (जैसे कि मेरी कक्षा असाइनमेंट ...), तो आप 1 तर्क के साथ एक रैपर फ़ंक्शन का उपयोग कर सकते हैं, बाकी को अपने शरीर में मूल को पास कर सकते हैं; अर्थात:

extraArguments = value 
def myFunc(arg): 
    # call the target function 
    return Func(arg, extraArguments) 


map(myFunc, itterable) 

गंदा & बदसूरत, अभी भी चाल

+1

एक बंद, मुझे लगता है कि यह कुछ जोड़ता है, साथ ही एक। आंशिक कार्य के समान, स्वीकृत उत्तर के रूप में। –

+1

'myFunc' को वापस लौटने की आवश्यकता है Func (arg, extraArguments) ' –

+0

मैं @ PM2Ring को सही करता हूं, यह सच है; कोड अपडेट किया गया। – Todor

26

करता डॉक्स स्पष्ट रूप से सुझाव है कि यह itertools.repeat के लिए मुख्य इस्तेमाल होता है:

पुनरावर्तक कि रिटर्न बार बार आपत्ति बनाओ। जब तक तर्क तर्क निर्दिष्ट नहीं किया जाता है तब तक अनिश्चित काल तक चलता है। कॉल किए गए फ़ंक्शन के लिए परिवर्तनीय पैरामीटर के लिए map() पर तर्क के रूप में उपयोग किया जाता है। एक tuple रिकॉर्ड का एक invarian हिस्सा बनाने के लिए zip() के साथ भी उपयोग किया जाता है।

और को times तर्क के रूप में पास करने का कोई कारण नहीं है; map जैसे ही पहला iterable सेवन किया जाता है बंद हो जाता है, तो एक अनंत iterable बिल्कुल ठीक है:

>>> list(map(pow, range(10), repeat(2))) 
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81] 

यह बनाता है:

>>> from operator import add 
>>> from itertools import repeat 
>>> list(map(add, [1,2,3], repeat(4))) 
[5, 6, 7] 

वास्तव में, इस repeat डॉक्स में के लिए उदाहरण के बराबर है एक अच्छा आलसी-कार्यात्मक-भाषा-वाई समाधान के लिए जो पाइथन-इटरेटर शर्तों में पूरी तरह से पठनीय है।

+0

+1 यह स्वीकार्य उत्तर होना चाहिए। यह निश्चित रूप से, कुछ निरंतर और अन्य सूचियों या जेनरेटर के साथ, पैरामीटर की किसी भी संख्या तक फैली हुई है। उदाहरण: 'def f (x, y, z): \\ वापसी'। 'शामिल हों ([x, y, z])' और फिर: 'सूची (मानचित्र (एफ, सूची (' abc '), दोहराना ('foo'), सूची ('defgh')) 'रिटर्न' ['a.foo.d', 'b.foo.e', 'c.foo.f'] '। –

+4

पायथन 2 में, 'दोहराना() 'के लिए लम्बा तर्क प्रदान करना आवश्यक है, क्योंकि' मैप() 'तब तक चलेगा जब तक कि सभी लापता मूल्यों के लिए' कोई नहीं 'भरने पर पाइथन के उस संस्करण में _longest_ iterator समाप्त हो जाए। यह कहकर कि पैरामीटर पास करने के लिए "कारण नहीं है" गलत है। –

0

एक अन्य विकल्प है:

results = [] 
for x in [1,2,3]: 
    z = add(x,2) 
    ... 
    results += [f(z,x,y)] 

यह स्वरूप बहुत उपयोगी है जब कई कार्यों बुला।

6

कभी कभी मैं (जैसे pandas.apply विधि का उपयोग कर के रूप में) इसी तरह की परिस्थितियों closures

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

कुछ इस तरह:

>>> add_constant(2)(3) 
5 

कौन सा आप किसी भी स्थिति जहां में इसका इस्तेमाल करने की अनुमति देता है:

def add(x, y): 
    return x + y 

def add_constant(y): 
    def f(x): 
     return add(x, y) 
    return f 

फिर, add_constant(y) एक समारोह जो किसी भी मूल्य के लिए y जोड़ने के लिए इस्तेमाल किया जा सकता रिटर्न पैरामीटर एक समय में दिए जाते हैं:

>>> map(add_constant(2), [1,2,3]) 
[3, 4, 5] 

संपादित

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

>>> map(lambda x: add(x, 2), [1, 2, 3]) 
[3, 4, 5] 
1

करने के लिए कई तर्क पास करने के लिए एक map समारोह।

def q(x,y): 
    return x*y 

print map (q,range(0,10),range(10,20)) 

यहाँ क्ष कई तर्क यह है कि नक्शा() कॉल के साथ कार्य है। यकीन है कि, दोनों की लंबाई पर्वतमाला यानी सुनिश्चित

len (range(a,a')) and len (range(b,b')) are equal. 
4

मानचित्र कई तर्क हो सकते हैं, मानक तरीका

map(add, a, b) 

अपने प्रश्न में है, यह होना चाहिए

map(add, a, [2]*len(a)) 
5

सही जवाब आपके विचार से सरल है। आप कार्य करें:

map(add, [(x, 2) for x in [1,2,3]]) 

और ऐड के कार्यान्वयन को बदलने एक टपल यानी

def add(t): 
    x, y = t 
    return x+y 

यह किसी भी जटिल उपयोग के मामले जहां दोनों पैरामीटर जोड़ गतिशील हैं संभाल कर सकते हैं लेने के लिए।

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