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


155

हम कहते हैं कि हमारे पास एक फंक्शन ऐड है

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

हम सरणी के लिए मानचित्र फ़ंक्शन लागू करना चाहते हैं

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

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

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


20
यह बिल्कुल लिस्प की तरह ही है: map(add,[1,2,3],[2]*3) सामान्य तौर mapपर किसी फ़ंक्शन को इसके पहले तर्क के रूप में लेता है, और यदि यह फ़ंक्शन K तर्क लेता है, तो आपको KaddTriple(a,b,c) -> map(addTriple,[...],[...],[...])
iterable

जवाबों:


188

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

[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
हाँ, लेकिन यह मानचित्र कार्य की तुलना में कितना तेज़ है?
शान

@ शान: बहुत समान है, खासकर अगर add()एक गैर-तुच्छ कार्य है
स्वेन मार्नाच

2
@ शान: इस मामले में न्यूमी पर एक नज़र। यदि यह वास्तव में आपके लिए एक मुद्दा है, तो सूची बोध के बीच गति अंतर और map()किसी भी तरह से मदद नहीं करेगा।
स्वेन मार्नाच

3
@ शान: जैसा कि मैंने पहले कहा, न्यूमपी पर एक नज़र। यह छोरों को तेजी से ऊपर उठाने में मदद कर सकता है, बशर्ते कि उन्हें वेक्टर बनाया जा सके।
स्वेन मार्नाच

1
@abarnert: यह स्पष्ट नहीं है कि ओपी पायथन 2 या 3 का उपयोग कर रहा है या नहीं। यह सुनिश्चित करने के लिए कि उदाहरण पायथन 2 में काम करता है, मैंने पैरामीटर को शामिल किया। (ध्यान दें कि पायथन 2 की map()तरह व्यवहार करता है zip_longest(), जबकि यह zip()पायथन 3 की तरह व्यवहार करता है )
स्वेन मार्नाच

60

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

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

और तर्क के len([1,2,3])रूप में पास का कोई कारण नहीं timesहै; mapजैसे ही पहले चलने योग्य का सेवन किया जाता है, वैसे ही बंद हो जाता है, इसलिए एक अनंत चलने योग्य पूरी तरह से ठीक है:

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

वास्तव में, यह repeatडॉक्स के लिए उदाहरण के बराबर है :

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

यह एक अच्छा आलसी-कार्यात्मक-भाषा-वाई समाधान के लिए बनाता है जो पायथन-पुनरावृत्त शब्दों में भी पूरी तरह से पठनीय है।


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

5
पायथन 2 में, लंबाई तर्क प्रदान करना आवश्यक है repeat(), क्योंकि पायथन के उस संस्करण में सबसे लंबे समयmap() तक चलने वाला थकावट समाप्त होने तक चलेगा , सभी लापता मानों के लिए भरना । यह कहना कि पैरामीटर पारित करने के लिए "कोई कारण नहीं है" गलत है। None
स्वेन मार्नाच

@SvenMarnach की टिप्पणी मामूली नहीं है: पायथन 3 और पायथन 2 का व्यवहार काफी भिन्न होता है!
अगस्टिन

36

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

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

यदि आप वास्तव में , वास्तव में , वास्तव में उपयोग करना चाहते हैं map, तो इसे पहले तर्क के रूप में एक अनाम फ़ंक्शन दें:

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

16

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

map(add, a, b)

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

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

निश्चित नहीं है कि उनके सवाल का क्या मतलब है, लेकिन मुझे लगता है कि ऐड 2 मान को स्वीकार करते हैं और उन 2 को तय नहीं किया गया है और उपयोगकर्ता से आना चाहिए जैसे कि arg1 आ रहा है। तो इस मामले में हमें मानचित्र के तहत ऐड (x, y) को कैसे कॉल करना चाहिए?
बिमलेश शर्मा

15

सही उत्तर आपके विचार से सरल है। बस करो:

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

और जोड़ने के कार्यान्वयन को बदलने के लिए एक tuple यानी

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

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


14

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

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

कुछ इस तरह:

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

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

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

>>> add_constant(2)(3)
5

जो आपको किसी भी स्थिति में इसका उपयोग करने की अनुमति देता है जहां पैरामीटर एक बार में दिए जाते हैं:

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

संपादित करें

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

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

13

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

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

यह मान रहा है कि आपका वास्तविक एप्लिकेशन गणितीय कार्य कर रहा है (जिसे वेक्टर किया जा सकता है)।


10

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

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


map(myFunc, itterable)

गंदा और बदसूरत, अभी भी चाल है


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

1
myFuncकी जरूरत हैreturn Func(arg, extraArguments)
PM 2Ring

मैं सही @ PM2Ring खड़ा हूँ, यह सच है; कोड को अद्यतन किया।
टोडर मिनाकोव

फंक को कहाँ परिभाषित किया गया है? क्योंकि मुझे फंक के लिए एक नाम त्रुटि मिल रही है
निखिल मिश्रा

Funcआपके मूल कार्य का नाम है - ओपी तंग के addलिए उदाहरण के लिए होगा
टोडर मिनकोव

6

मेरा मानना ​​है कि स्टार्मैप की आपको आवश्यकता है:

from itertools import starmap


def test(x, y, z):
    return x + y + z

list(starmap(test, [(1, 2, 3), (4, 5, 6)]))

अपने उदाहरण में टाइपो: सूची (स्टॉर्मैप (परीक्षण, [(1, 2, 3), (4, 5, 6)])
तीबू

अरे हाँ। धन्यवाद :)
Shiki.Yang

1

किसी mapफ़ंक्शन के लिए कई तर्क पास करना ।

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

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

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

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

1

इन:nums = [1, 2, 3]

इन:map(add, nums, [2]*len(nums))

बाहर:[3, 4, 5]


1
यह प्रश्न का उत्तर प्रदान नहीं करता है। आप इसी तरह के प्रश्नों की खोज कर सकते हैं , या उत्तर खोजने के लिए पेज के दाईं ओर संबंधित और जुड़े प्रश्नों को देख सकते हैं। यदि आपके पास संबंधित लेकिन अलग प्रश्न है, तो एक नया प्रश्न पूछें , और संदर्भ प्रदान करने में मदद करने के लिए इस पर एक लिंक शामिल करें। देखें: प्रश्न पूछें, उत्तर प्राप्त करें, कोई ध्यान भंग न करें
टिम डाइकमैन

1

आप लैम्बडा को मानचित्र के साथ शामिल कर सकते हैं:

list(map(lambda a: a+2, [1, 2, 3]))

1
def func(a, b, c, d):
 return a + b * c % d
map(lambda x: func(*x), [[1,2,3,4], [5,6,7,8]])

फ़ंक्शन कॉल को लंबोदर के साथ लपेटकर और स्टार अनपैक का उपयोग करके, आप मनमाने ढंग से तर्कों के साथ मैप कर सकते हैं।


लैम्ब्डा बहुत धीमा है, इसके बजाय फंक्शनलबुल का उपयोग करें
वांग

0

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

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

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

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.