मैप फंक्शन को समझना


311
map(function, iterable, ...)

चलने की हर वस्तु पर फ़ंक्शन लागू करें और परिणामों की सूची लौटाएं। यदि अतिरिक्त पुनरावृत्त तर्क पारित किए जाते हैं, तो फ़ंक्शन को कई तर्कों को लेना चाहिए और समानांतर में सभी पुनरावृत्तियों से आइटम पर लागू किया जाना चाहिए।

यदि एक चलने योग्य दूसरे की तुलना में कम है, तो यह माना जाता है कि कोई भी आइटम नहीं है।

यदि फ़ंक्शन है None, तो पहचान फ़ंक्शन माना जाता है; यदि कई तर्क होते हैं, तो map()एक सूची देता है जिसमें सभी पुनरावृत्तियों (एक प्रकार का पारगमन संचालन) से संबंधित वस्तुओं से युक्त टुपल्स शामिल हैं।

पुनरावृत्त तर्क एक अनुक्रम या किसी भी चलने योग्य वस्तु हो सकते हैं; परिणाम हमेशा एक सूची है।

कार्टेशियन उत्पाद बनाने में यह क्या भूमिका निभाता है?

content = map(tuple, array)

वहाँ कहीं भी एक टपल लगाने का क्या प्रभाव पड़ता है? मैंने यह भी देखा कि बिना मानचित्र कार्य के आउटपुट होता है abcऔर इसके साथ, यह है a, b, c

मैं इस फंक्शन को पूरी तरह से समझना चाहता हूं। संदर्भ परिभाषाओं को समझना भी कठिन है। बहुत ज्यादा फैंस का हुजूम।


2
आप वास्तव में क्या हासिल करना चाहते हैं और विशेष रूप से आप क्यों उपयोग करना चाहते हैं map?
क्रिश हार्पर

3
@EbMaster हाँ, आपके द्वारा चिपकाए गए दस्तावेज़ में पहले वाक्य के अनुसार - "लागू होने वाले हर आइटम पर फ़ंक्शन लागू करें"। बाकी पैराग्राफ अधिक जटिल मामलों के बारे में है - जैसे map(None, a, b, c)कि क्या करना है zip(a, b, c)। लेकिन आप बहुत कम ही देखते हैं कि व्यवहार में, ठीक है क्योंकि zipकॉल समकक्ष है।
पीवीसी

9
मैं अजगर को सीखने की बहुत कोशिश कर रहा हूं और जब भी मैं python.org में परिभाषा खोलता हूं। पहले वाक्य के बाद, मुझे कुछ भी समझ नहीं आया। ठीक है। धन्यवाद।
वेब मास्टर

2
tupleएक फ़ंक्शन है (ठीक है, इसकी तुलना में इसकी अधिक सूक्ष्मता है, लेकिन यह एक फ़ंक्शन की तरह व्यवहार करता है) जो एक पुनरावृत्ति लेता है, और आपको समान तत्वों के साथ एक ट्यूपल देता है - इसलिए tuple([1, 2, 3])इसके बराबर है (1, 2, 3)। के लिए map(tuple, array), arrayपुनरावृत्तियों का एक पुनरावृत्ति होगा (सूचियों की एक सूची पर विचार करें), और यह आपको प्रत्येक आंतरिक सूची को एक टुपल में बदल देता है।
पीवीसी

1
सामान्य तौर पर, यह किसी भी फ़ंक्शन के प्रलेखन का पहला वाक्य है जो सबसे अधिक मायने रखता है। अगर आप इसे समझते हैं, तो आपको इसका फायदा मिलता है। इसका बाकी हिस्सा बहुत विस्तार से बताता है, और इनमें से कुछ के साथ शुरू करने के लिए थोड़ा अपारदर्शी होगा , और आपको "ओह, यह वही है!" देखने से पहले इसके आधार पर एक अजीब मुहावरे पर आने की आवश्यकता हो सकती है । लेकिन एक बार जब आप कुछ बिल्डिंस के लिए उस लाइटबल्ब पल को प्राप्त करते हैं, तो आपको डॉक्स को थोड़ा और आसानी से समझने में सक्षम होना चाहिए।
पीवीसी

जवाबों:


441

mapविशेष रूप से अजगर नहीं है। मैं इसके बजाय सूची समझ का उपयोग करने की सलाह दूंगा:

map(f, iterable)

मूल रूप से इसके बराबर है:

[f(x) for x in iterable]

mapअपने आप में एक कार्टेशियन उत्पाद नहीं किया जा सकता है, क्योंकि इसकी आउटपुट सूची की लंबाई हमेशा इसकी इनपुट सूची के समान होती है। यद्यपि आप एक कार्टेसियन उत्पाद की सूची समझ के साथ कर सकते हैं:

[(a, b) for a in iterable_a for b in iterable_b]

वाक्यविन्यास थोड़ा भ्रमित है - यह मूल रूप से इसके बराबर है:

result = []
for a in iterable_a:
    for b in iterable_b:
        result.append((a, b))

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

1
मैं गुणों के लिए मानचित्र का उपयोग कैसे करूं? mapअसमानता क्या है [v.__name__ for v in (object, str)]?
एक एसयू

@ASz कैसे map(lambda v: v.__name__, list)?
किलन

10
मानचित्र तेज है क्योंकि यह
पुनरावृत्तियों की

1
@anati मुझे लगता है mapकि कभी-कभी समझ से अधिक तेज था , कभी-कभी, फ़ंक्शन कॉल ओवरहेड के कारण ठीक नहीं? विशेष रूप से, मैंने जो सीखा है वह यह है कि जब mapआपको एक अतिरिक्त फ़ंक्शन कॉल की आवश्यकता होती है, तो समझ में तेजी आती है? उदाहरण के लिए, मुझे विश्वास है कि map(lambda foo: foo.bar, my_list)की तुलना में धीमी थी foo.bar for foo in my_list, और यह भी अतिरिक्त कार्य कॉल की वजह map(operator.add, my_list_of_pairs)से धीमी है x + y for x, y in my_list_of_pairs
mtraceur

86

mapएक कार्टेशियन उत्पाद से बिल्कुल भी संबंधित नहीं है, हालांकि मैं कल्पना करता हूं कि कार्यात्मक प्रोग्रामिंग में किसी ने अच्छी तरह से काम किया है जो किसी का उपयोग करने के तरीके को समझने के लिए कुछ असंभव के साथ आ सकता है map

map पायथन 3 इस के बराबर है:

def map(func, iterable):
    for i in iterable:
        yield func(i)

और पायथन 2 में एकमात्र अंतर यह है कि यह yieldआईएनजी के बजाय एक बार में सभी को वापस करने के लिए परिणामों की पूरी सूची का निर्माण करेगा ।

हालांकि पायथन सम्मेलन आमतौर पर कॉल के रूप में एक ही परिणाम प्राप्त करने के लिए सूची समझ (या जनरेटर अभिव्यक्ति) को mapप्राथमिकता देता है, खासकर यदि आप पहले तर्क के रूप में एक लंबो अभिव्यक्ति का उपयोग कर रहे हैं:

[func(i) for i in iterable]

इस सवाल पर टिप्पणियों में आपके द्वारा पूछे गए एक उदाहरण के रूप में - "एक स्ट्रिंग को एक सरणी में बदल दें", 'सरणी' के द्वारा आप शायद या तो टपल चाहते हैं या एक सूची (दोनों ही अन्य भाषाओं से एरे की तरह थोड़ा व्यवहार करते हैं) -

 >>> a = "hello, world"
 >>> list(a)
['h', 'e', 'l', 'l', 'o', ',', ' ', 'w', 'o', 'r', 'l', 'd']
>>> tuple(a)
('h', 'e', 'l', 'l', 'o', ',', ' ', 'w', 'o', 'r', 'l', 'd')

mapयदि आप एक तार के बजाय तारों की सूची के साथ शुरू करते हैं तो यहां इसका उपयोग होगा - mapउन सभी को व्यक्तिगत रूप से सूचीबद्ध कर सकते हैं:

>>> a = ["foo", "bar", "baz"]
>>> list(map(list, a))
[['f', 'o', 'o'], ['b', 'a', 'r'], ['b', 'a', 'z']]

ध्यान दें कि map(list, a)पायथन 2 में समतुल्य है, लेकिन पायथन 3 में आपको listकॉल की आवश्यकता है यदि आप इसे forलूप में फीड करने के अलावा कुछ भी करना चाहते हैं (या प्रोसेसिंग फंक्शन जैसे sumकि इसे केवल एक पुनरावृत्ति की आवश्यकता है, और अनुक्रम नहीं)। लेकिन यह भी ध्यान दें कि एक सूची की समझ आमतौर पर पसंद की जाती है:

>>> [list(b) for b in a]
[['f', 'o', 'o'], ['b', 'a', 'r'], ['b', 'a', 'z']]

नक्शा (मज़ेदार x -> (x, x)) समझने में मुश्किल नहीं लगता है ... (हालांकि मानचित्र से एक सच्चे कार्टेसियन उत्पाद प्राप्त करना असंभव होगा, कुछ भी मानचित्र हमेशा एक सूची का कुछ रूप होता है)
क्रिस्टोफर मिन्स्की

36

map स्रोत के प्रत्येक तत्व के लिए एक फ़ंक्शन लागू करके एक नई सूची बनाता है:

xs = [1, 2, 3]

# all of those are equivalent — the output is [2, 4, 6]
# 1. map
ys = map(lambda x: x * 2, xs)
# 2. list comprehension
ys = [x * 2 for x in xs]
# 3. explicit loop
ys = []
for x in xs:
    ys.append(x * 2)

n-ary mapएक साथ इनपुट iterables को जिप करने के बराबर है और फिर उस मध्यवर्ती ज़िपित सूची के प्रत्येक तत्व पर परिवर्तन फ़ंक्शन को लागू करता है। यह कार्टेशियन उत्पाद नहीं है:

xs = [1, 2, 3]
ys = [2, 4, 6]

def f(x, y):
    return (x * 2, y // 2)

# output: [(2, 1), (4, 2), (6, 3)]
# 1. map
zs = map(f, xs, ys)
# 2. list comp
zs = [f(x, y) for x, y in zip(xs, ys)]
# 3. explicit loop
zs = []
for x, y in zip(xs, ys):
    zs.append(f(x, y))

मैंने zipयहां उपयोग किया है, लेकिन mapव्यवहार वास्तव में थोड़ा अलग होता है जब पुनरावृत्तियां समान आकार की नहीं होती हैं - जैसा कि इसके प्रलेखन में उल्लेख किया गया है, इसमें पुनरावृत्तियों का विस्तार है None


1
जटिल, इस पोस्ट को पचाने की कोशिश कर रहा है
वेब मास्टर

1
@EbMaster इसके बारे में क्या जटिल है?
जॉसी कैलडरन

मेरी राय में सबसे अच्छा जवाब। एक समारोह के रूप में उदाहरण में लैम्ब्डा का उपयोग करना इसे बहुत स्पष्ट करता है।
Sheldonzy

दुर्भाग्य से ये सभी समतुल्य नहीं हैं - आउटपुट [2,4,6]लिस्ट कॉम्प्रिहेंशन और स्पष्ट लूप्स के लिए है, लेकिन मैप एक मैप ऑब्जेक्ट लौटाता है - उदाहरण के लिए मुझे यह मिलता है: <map at 0x123a49978>जिसे मुझे तब एक सूची में शामिल करना होगा।
लीरसेज

20

थोड़ा सा सरलीकरण, आप map()कुछ इस तरह से करने की कल्पना कर सकते हैं :

def mymap(func, lst):
    result = []
    for e in lst:
        result.append(func(e))
    return result

जैसा कि आप देख सकते हैं, यह एक फ़ंक्शन और एक सूची लेता है, और इनपुट सूची में प्रत्येक तत्व में फ़ंक्शन को लागू करने के परिणाम के साथ एक नई सूची देता है। मैंने कहा "थोड़ा सरल" क्योंकि वास्तविकता में एक से अधिकmap() प्रक्रिया कर सकते हैं पुनरावृत्तियों :

यदि अतिरिक्त पुनरावृत्त तर्क पारित किए जाते हैं, तो फ़ंक्शन को कई तर्कों को लेना चाहिए और समानांतर में सभी पुनरावृत्तियों से आइटम पर लागू किया जाना चाहिए। यदि एक चलने योग्य दूसरे की तुलना में कम है, तो यह माना जाता है कि कोई भी आइटम नहीं है।

प्रश्न में दूसरे भाग के लिए: कार्टेशियन उत्पाद बनाने में यह क्या भूमिका निभाता है? अच्छी तरह से, इस तरह की एक सूची के कार्टेसियन उत्पाद पैदा करने के लिए इस्तेमाल किया जा map() सकता है:

lst = [1, 2, 3, 4, 5]

from operator import add
reduce(add, map(lambda i: map(lambda j: (i, j), lst), lst))

... लेकिन सच्चाई बताने के product()लिए, समस्या को हल करने का एक बहुत ही सरल और प्राकृतिक तरीका है:

from itertools import product
list(product(lst, lst))

किसी भी तरह से, परिणाम के lstरूप में ऊपर परिभाषित के कार्टेशियन उत्पाद है :

[(1, 1), (1, 2), (1, 3), (1, 4), (1, 5),
 (2, 1), (2, 2), (2, 3), (2, 4), (2, 5),
 (3, 1), (3, 2), (3, 3), (3, 4), (3, 5),
 (4, 1), (4, 2), (4, 3), (4, 4), (4, 5),
 (5, 1), (5, 2), (5, 3), (5, 4), (5, 5)]

17

map()समारोह वहाँ उसी प्रक्रिया सूचियों, जेनरेटर, तार, और अन्य सामग्री की तरह, एक iterable डेटा संरचना में हर आइटम के लिए लागू है।

आइए एक उदाहरण देखें: map() किसी सूची में प्रत्येक आइटम पर पुनरावृति कर सकते हैं और प्रत्येक आइटम पर एक फ़ंक्शन लागू कर सकते हैं, इससे नई सूची वापस आ जाएगी (आपको वापस दे दी जाएगी)।

कल्पना कीजिए कि आपके पास एक फ़ंक्शन है जो एक नंबर लेता है, उस नंबर पर 1 जोड़ता है और इसे वापस करता है:

def add_one(num):
  new_num = num + 1
  return new_num

आपके पास संख्याओं की एक सूची भी है:

my_list = [1, 3, 6, 7, 8, 10]

यदि आप सूची में प्रत्येक संख्या को बढ़ाना चाहते हैं, तो आप निम्न कार्य कर सकते हैं:

>>> map(add_one, my_list)
[2, 4, 7, 8, 9, 11]

नोट: न्यूनतम map() दो तर्कों की आवश्यकता है। पहला एक फंक्शन का नाम और दूसरा किसी लिस्ट की तरह।

आइए देखते हैं कुछ और बेहतरीन चीजें map()map()एकाधिक पुनरावृत्तियाँ (सूचियाँ, तार, आदि) ले सकते हैं और एक तर्क के रूप में कार्य करने के लिए प्रत्येक चलने योग्य से एक तत्व पास करते हैं।

हमारे पास तीन सूचियाँ हैं:

list_one = [1, 2, 3, 4, 5]
list_two = [11, 12, 13, 14, 15]
list_three = [21, 22, 23, 24, 25]

map() आप एक विशिष्ट सूची में तत्वों के अलावा रखने वाली एक नई सूची बना सकते हैं।

अब याद है map(), एक समारोह की जरूरत है। इस बार हम अंतर्निहित sum()फ़ंक्शन का उपयोग करेंगे । रनिंग map()निम्न परिणाम देता है:

>>> map(sum, list_one, list_two, list_three)
[33, 36, 39, 42, 45]

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


8

पायथन 3 - मानचित्र (दुर्गंध, चलने योग्य)

एक बात जिसका पूरी तरह से उल्लेख नहीं किया गया था (हालाँकि @BlooB थोड़े ने इसका उल्लेख किया है) यह है कि नक्शा एक मैप ऑब्जेक्ट देता है एक सूची नहीं । यह एक बड़ा अंतर है जब यह प्रारंभ और पुनरावृत्ति पर समय के प्रदर्शन की बात आती है। इन दो परीक्षणों पर विचार करें।

import time
def test1(iterable):
    a = time.clock()
    map(str, iterable)
    a = time.clock() - a

    b = time.clock()
    [ str(x) for x in iterable ]
    b = time.clock() - b

    print(a,b)


def test2(iterable):
    a = time.clock()
    [ x for x in map(str, iterable)]
    a = time.clock() - a

    b = time.clock()
    [ str(x) for x in iterable ]
    b = time.clock() - b

    print(a,b)


test1(range(2000000))  # Prints ~1.7e-5s   ~8s
test2(range(2000000))  # Prints ~9s        ~8s

जैसा कि आप देख सकते हैं कि मैपिंग फंक्शन को इनिशियलाइज़ करने में लगभग कोई समय नहीं लगता है। हालाँकि, मैप ऑब्जेक्ट के माध्यम से पुनरावृति बस चलने योग्य के माध्यम से पुनरावृत्त होने से अधिक समय लेता है। इसका मतलब यह है कि फ़ंक्शन को मैप करने के लिए पारित किया गया है () प्रत्येक तत्व पर लागू नहीं होता है जब तक कि तत्व पुनरावृत्ति में नहीं पहुंचता है। यदि आप एक सूची उपयोग सूची समझ चाहते हैं। यदि आप एक लूप के माध्यम से पुनरावृति करने की योजना बनाते हैं और किसी बिंदु पर टूटेंगे, तो मानचित्र का उपयोग करें।

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