2012-04-25 9 views
8

के लिए मानचित्र लागू करना दो तर्कों के साथ निम्न फ़ंक्शन f को देखते हुए, केवल x पर मानचित्र लागू करने का मानक तरीका क्या है?आंशिक तर्क

def f (x,y): 
    print x,y 

अधिक विशेष रूप से, मैं एक पंक्ति में मानचित्र के साथ निम्नलिखित ऑपरेशन करना चाहता हूं।

list=[1,2,3] 
fixed=10 
for s in list: 
    f(s,fixed) 

एक तरह से ऐसा करने के लिए है:

import functools 
map(functools.partial(lambda x,y:f(y,x),fixed),list) 

एक बेहतर तरीका क्या है?

उत्तर

14

सबसे पहले, लैम्ब्डा और आंशिक उपयोग करने के लिए कोई जरूरत नहीं है - वे कर रहे हैं विकल्प:

map(lambda x:f(x,fixed),srclist) 

दूसरे, आप सिर्फ partial साथ दूसरा तर्क बाध्य है, जब तक आप तर्क का नाम जानते हैं सकता है:

[f(x, fixed) for x in srclist] 
+1

क्या आप इस बात पर टिप्पणी कर सकते हैं कि इन तीन तरीकों का प्रदर्शन कैसे ढेर हुआ? – chase

+1

@ चेज वेल, आखिरी में कोई वास्तविक आंशिक अनुप्रयोग शामिल नहीं है, इसलिए यह किसी भी ओवरहेड से बचाता है। दूसरे दो के रूप में, मैं नहीं कह सकता। इस प्रकार का माइक्रो-ऑप्टिमाइज़ेशन तब तक नहीं होना चाहिए जब तक आप किसी हॉटस्पॉट को पहचान न लें। – Marcin

+0

आम तौर पर मैं सहमत हूं। यद्यपि कभी-कभी 2 साल पुराने एसओ सवालों के माध्यम से खोजता है जब उन्हें एक हॉटस्पॉट मिल जाता है;) प्रोफ़ाइल के लिए पर्याप्त आसान होना चाहिए, हालांकि मैं व्यक्तिगत रूप से स्पष्टता के लिए अंतिम समाधान पसंद करता हूं। – chase

5
:

map(functools.partial(f,y=fixed),srclist) 

वैकल्पिक रूप से, एक सूची समझ का उपयोग

या map() का भी उपयोग न करें, इसके बजाय सूची की समझ का उपयोग करें।

[f(fixed, x) for x in thelist] 

पुनश्च: एक चर नाम के रूप में list का उपयोग नहीं करते हैं, यह (सूची प्रकार) एक महत्वपूर्ण निर्मित नाम है।

1

क्या बुराई है:

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

l = [1, 2, 3] 

from functools import partial 
plus10 = map(partial(add, y=10), l) 
print plus10 

## [11, 12, 13] 
+0

यह अपठनीय है (और मैंने सोचा कि अजगर स्वयं व्याख्या कर रहा था?)। सूची समझ उदाहरण अधिक पढ़ने योग्य हैं। – Ingo

+0

@Ingo: निश्चित रूप से, ओपी को छोड़कर समझ के बारे में कुछ भी नहीं कहा। – georg

5

दो तर्कों निम्नलिखित समारोह को देखते हुए च, केवल एक्स के लिए नक्शे लागू करने के लिए मानक तरीका क्या है?

currying और आंशिक आवेदन

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

इसके आसपास काम करने के लिए, कई चालें हैं, लेकिन अवधारणात्मक रूप से आप केवल फ़ंक्शन को "करी" करना चाहते हैं। यही है, f(x,y) को f(x) में बदलें जो एक नया फ़ंक्शन g(y) देता है।

-- curry: take a function from (x,y) to one from x to a function from y to z 
curry :: ((x,y) -> z) -> (x -> y -> z) 
curry f x y  = f (x, y) 

तो curry, अपने curried f और उसके उत्पाद तर्क लेता है अलग, और तर्क लागू होता है एक बार वे सब उपलब्ध हैं:

भाषाओं में जो डिफ़ॉल्ट रूप से curried रहे हैं, आप के रूप में आसानी इस अनुवाद लिख सकते हैं। इसके विपरीत भी बहुत आसान है:

uncurry :: (x -> y -> z) -> ((x,y) -> z) 
uncurry f (x,y) = f x y 

यह आंशिक एप्लिकेशन से कैसे संबंधित है?

  • Currying एक समारोह है कि (n -उत्पाद) तर्क की एक संरचना लेता है लेता है, और n तर्क लेने एक नया कार्य देता है।
  • आंशिक आवेदन n तर्क के एक समारोह लेता है और उन्हें कश्मीर तर्क पर लागू होता है, एन-कश्मीर शेष बहस के एक समारोह उपज।

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

मुझे लगता है कि आंशिक एप्लिकेशन निःशुल्क है, क्योंकि यह एक करीबी-डिफ़ॉल्ट-डिफ़ॉल्ट वातावरण में होना अधिक लचीला है। ऐसे माहौल में, modify a data structure into a pipeline पर एक साथ श्रृंखला को जोड़ना आम बात है। जैसे पूर्णांक संशोधनों की एक पाइप लाइन:

(+1) . (*2) . (^3) $ 7 

सिर्फ आंशिक रूप से लागू किया, uncurried कार्यों की एक श्रृंखला, रचना की, प्रत्येक पिछले फ़ंक्शन के परिणाम पर काम है। यह अच्छा हो सकता है, क्योंकि यह चिंताओं को दृष्टि से अलग करता है।

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