2012-01-06 18 views
7

सरल प्रश्न एक सूची के लिए एक समारोह का मिलान, इसदूर करने के लिए कैसे अतिरिक्त {} जब

Clear[a, b, c, d, e, f]; 
lst = {{a, b}, {c, d}, {e, f}}; 

की तरह एक सूची दी और लगता है मुझे एक समारोह इस तरह परिभाषित किया है:

foo[x_,y_]:=Module[{},...] 

और मैं इस सूची को यह समारोह लागू करना चाहते हैं, तो अगर मैं

Map[foo, lst] 

टाइप यह

देता है
{foo[{a, b}], foo[{c, d}], foo[{e, f}]} 

मैं इसे के रूप में

{foo[a, b], foo[c, d], foo[e, f]} 

तो यह काम करता है बाहर आना चाहते हैं।

ऐसा करने का सबसे अच्छा तरीका क्या है? मान लें मैं समारोह foo [] परिभाषा संशोधित नहीं कर सकते (कहते हैं कि इसे बनाने में है)

केवल 2 तरीके मैं जानता हूँ कि अब

Map[foo[#[[1]], #[[2]]] &, lst] 
{foo[a, b], foo[c, d], foo[e, f]} 

(बहुत ज्यादा काम कर रहे हैं), या

MapThread[foo, Transpose[lst]] 
{foo[a, b], foo[c, d], foo[e, f]} 

(कम टाइपिंग, लेकिन पहले स्थानांतरित करने की आवश्यकता है)

प्रश्न: उपर्युक्त करने के लिए कोई और बेहतर तरीका? मैंने दूसरे मानचित्र और उसके दोस्तों को देखा, और मैं जो कुछ भी करता हूं उससे ज्यादा सीधे करने के लिए कोई फ़ंक्शन नहीं देख सका।

+1

[संबंधित] (http://stackoverflow.com/q/5746717/499167) प्रश्न: ** गणित में तर्कों को सूची लागू करें ** – tomd

उत्तर

14

आप Level 1 या उसके संक्षिप्त रूप में Apply की जरूरत है, @@@

[email protected]@@lst  
{foo[a, b], foo[c, d], foo[e, f]} 
7

एक संभव तरीका foo को List से lst के प्रत्येक तत्व के सिर को बदलने के लिए है:

foo @@ # & /@ lst 
{foo[a, b], foo[c, d], foo[e, f]} 
4

कुछ और से चुनने की संभावनाएं:

यह एक मैं योड के जवाब का एक और वर्बोज़ संस्करण है।यह सूची lst केवल (सिर foo के साथ सिर List बदल देता है) के स्तर 1 पर foo लागू होता है:

Apply[foo, lst, {1}] 

यह वही करता है, लेकिन सूची lst (अनिवार्य रूप से आंद्रेई का जवाब) से अधिक नक्शे Apply:

Map[Apply[foo, #] &, lst ] 

और यह सिर्फ [x] स्तर 1 से पैटर्न की सूची [x__] foo के साथ बदलता है:

Replace[lst, List[x__] -> foo[x], 1] 
6

बस दोनों तरीकों (@@@, @@ # & /@) की पेचीदा प्रदर्शन परीक्षणों की रिपोर्ट करने के:

 T = RandomReal[{1,100}, {1000000, 2}]; 

     H[F_Symbol, T_List] := 

        [email protected][F @@@ T;]/[email protected][F @@ # & /@ T;] 

     Table[{ToString[F], H[F, T]}, {F, {Plus, Subtract, Times, Divide, Power, Log}}] 

Out[3]= {{"Plus",  4.174757}, 
     {"Subtract", 0.2596154}, 
     {"Times", 3.928230}, 
     {"Divide", 0.2674164}, 
     {"Power", 0.3148629}, 
     {"Log",  0.2986936}} 

इन परिणामों यादृच्छिक है, लेकिन बहुत अलग डेटा आकार के लिए मोटे तौर पर आनुपातिक नहीं हैं।

@@@Subtract के लिए मोटे तौर पर 3-4 बार तेजी से होता है, Divide, Power, Log जबकि @@ # & /@Plus और Times एक और सवाल है, जो (के रूप में एक विश्वास कर सकते हैं) थोड़ा
द्वारा स्पष्ट किया जा सकता है को जन्म दे रही के लिए 4 बार तेजी से होता है निम्नलिखित मूल्यांकन:

[email protected]{Plus, Subtract, Times, Divide, Power, Log} 

केवल Plus और Times, जबकि बाकी के बीच में, गुण Flat और Orderless है केवल(जो अपेक्षाकृत सबसे अधिक कुशल लगता है) में भी OneIdentity विशेषता है।

संपादित

देखे गए प्रदर्शन को बूस्ट करने के लिए एक विश्वसनीय स्पष्टीकरण (लियोनिद Shifrin की टिप्पणी के लिए धन्यवाद) एक अलग मार्ग के साथ जाना चाहिए।

डिफ़ॉल्ट रूप से MapCompileLength -> 100 है क्योंकि हम SystemOptions["CompileOptions"] का मूल्यांकन कर सकते हैं। मानचित्र की autocompilation हम मूल्यांकन कर सकते हैं रीसेट करने के लिए:

SetSystemOptions["CompileOptions" -> "MapCompileLength" -> Infinity] 

अब हम एक बार फिर हमारे H मूल्यांकन द्वारा दोनों तरीकों के सापेक्ष प्रदर्शन परीक्षण कर सकते हैं - संबंधित प्रतीकों पर निष्पादन परीक्षण समारोह और सूची:

  Table[{ToString[F], H[F, T]}, {F, {Plus, Subtract, Times, Divide, Power, Log}}] 

Out[15]= {{"Plus",  0.2898246}, 
      {"Subtract", 0.2979452}, 
      {"Times",  0.2721893}, 
      {"Divide", 0.3078512}, 
      {"Power",  0.3321622}, 
      {"Log",  0.3258972}} 

इन परिणामों के बाद हम निष्कर्ष निकाल सकते हैं कि सामान्य रूप से योड के दृष्टिकोण (@@@) सबसे कुशल हैं, जबकि Plus और Times के मामले में आंद्रेई द्वारा प्रदान किया गया है Map के स्वचालित संकलन के कारण बेहतर पी का विकृति (@@ # & /@)।

+3

अगर हम याद करते हैं कि 'मानचित्र' ऑटोकॉम्पाइल जब यह हो, तो इतना परेशान नहीं है, और 'लागू करें' को केवल 3 सिर के लिए संकलित किया जा सकता है: 'प्लस',' टाइम्स 'और' सूची'। ओटीओएच, '@@@' autocompile नहीं है। आपको 'प्लस' और 'टाइम्स' के लिए '@@ # और/@' निर्माण में ऑटोकंपिलेशन के कारण दक्षता बूस्ट दिखाई देती हैं, और क्योंकि आपका इनपुट एक बड़ी पैक वाली सरणी है (जो ऑटोकंपिलेशन से लाभ प्राप्त करने की अनुमति देता है) –

+1

यह उत्तर भी देखें मेरा: http://stackoverflow.com/questions/6405304/memory-use-of-apply-vs-map-virtual-memory-use-and-lock-ups/6408489#6408489, और इसके नीचे की टिप्पणियां, के लिए इसी तरह के मामलों की अधिक चर्चा। –

+0

@ लियोनीड दिलचस्प लिंक और टिप्पणियों के लिए धन्यवाद। दरअसल, जब मैं 'टी 1 = सेपैकएडएरे [टी]' पर '' एच 'फ़ंक्शन का मूल्यांकन करता हूं,' प्लस' और 'टाइम्स 'की सापेक्ष दक्षता कारक 2 द्वारा लगभग धीमा हो जाती है, जबकि अन्य कार्यों को केवल कुछ पर्सेंट द्वारा ही किया जाता है, हालांकि' मानचित्र 'प्लस' और 'टाइम्स' के लिए अभी भी लगभग दो गुना तेज है। इस प्रभाव का कारण जाहिर तौर पर ऑटोकंपिलेशन है। दूसरी ओर, संबंधित कार्यों के गुणों पर टिप्पणियां अभी भी मान्य हैं और मुझे उम्मीद है कि किसी भी तरह की गलतफहमी नहीं होनी चाहिए। – Artes

3

Apply[] पर जवाब मौके पर ही कर रहे हैं, और ऐसा करना सही है, लेकिन आप क्या करने की कोशिश कर रहे थे क्या, एक Sequence[] सिर के साथ एक List[] सिर को बदलने के लिए किया गया था, अर्थात List[List[3,5],List[6,7]]List[Sequence[3,5],Sequence[6,7]] बन जाना चाहिए।

अनुक्रम सिर स्वाभाविक रूप से क्या रहता है अगर पैरामीटर के किसी भी सूची के सिर हटा दी जाती है, तो Delete[Plus[3,5],0] और Delete[{3,5},0] और Delete[List[3,5],0] सभी Sequence[3,5] उत्पादन होता है।

तो [email protected][#,0]&/@{{a, b}, {c, d}, {e, f}} आपको [email protected]@@{{a, b}, {c, d}, {e, f}} जैसा ही देगा।

वैकल्पिक रूप से, foo[#/.List->Sequence]&/@{{a, b}, {c, d}, {e, f}} वही काम करता है।

+1

मुझे इस बयान से असहमत होना है कि वह 'सूची [सूची [...] ..] 'सूची [अनुक्रम [...] ..]' में बदलना चाहता है। अधिक सही ढंग से, वह 'सूची [एफ [...] ..]' चाहता है, यानी वह आंतरिक सूचियों के सिर को 'एफ' में बदलना चाहता है। – rcollyer

+0

मैं मानता हूं कि यही वह अंततः "चाहता है"। मैं इसे एक अर्थ में कहना चाहता था "आप वहां पहुंचने के लिए क्या करना चाहते हैं ..." ;-) भ्रम के लिए खेद है। 'सूची [एफ [अनुक्रम [...]] प्राप्त करने के लिए, ...]' उन्हें अनुक्रमों की सूची में सूचियों की सूची बदलने के लिए एक तरीका चाहिए। इसे आंतरिक रूप से लागू करें। –

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