2012-10-04 10 views
36

निम्नलिखित काम करता है खूबसूरती से अजगर में:Unpacking तर्क: केवल नामित तर्क का अनुसरण कर सकते * अभिव्यक्ति

def f(x,y,z): return [x,y,z] 

a=[1,2] 

f(3,*a) 

a के तत्वों पैक के रूप में यदि आप इसे f(3,1,2) की तरह बुलाया था और उसे [3,1,2] देता है। आश्चर्यजनक! इसके बजाय बुला कि f(1,2,3) की तरह, मैं ": केवल नामित तर्क * अभिव्यक्ति का अनुसरण कर सकते सिंटैक्स त्रुटि" मिल की

f(*a,3) 

:

लेकिन मैं पहले दो तर्क में a के तत्वों को अनपैक नहीं कर सकते हैं।

मैं सोच रहा हूं कि ऐसा क्यों होना चाहिए और यदि कोई चालाक चाल है तो मुझे अस्थायी चर का उपयोग किए बिना तर्क सूचियों के मनमानी हिस्सों में अनपॅकिंग सरणी के बारे में पता नहीं हो सकता है।

+5

'एफ (* ए, 3) 'अब पाइथन 3.5 –

उत्तर

27

में मदद करता है रेमंड के रूप में हेटिंगर का जवाब बताता है, यह बदल सकता है पाइथन 3 और here is a related proposal में बदल गया है, जिसे स्वीकार कर लिया गया है। विशेष रूप से वर्तमान प्रश्न से संबंधित है, यहाँ है कि प्रस्ताव के लिए संभव परिवर्तन है कि चर्चा की गई में से एक है:

Only allow a starred expression as the last item in the exprlist. This would simplify the unpacking code a bit and allow for the starred expression to be assigned an iterator. This behavior was rejected because it would be too surprising.

तो वहाँ समारोह तर्क खोल के साथ प्रतिबंध के लिए कार्यान्वयन कारण हैं, लेकिन यह वास्तव में एक छोटे से आश्चर्य की बात है!

इस बीच, यहां वैकल्पिक हल के लिए मैं देख रहा था, बीती बातों की जांच में है स्पष्ट तरह का:

f(*(a+[3])) 
+3

कुछ कहता है और यदि 'ए' टुपल है:' एफ (* (ए + (3,))) ' – Hotschke

10

यह इस तरह से होना चाहिए। यह सिर्फ नियम था कि ग्विडो समझदार पाया गया।

अजगर 3 में, खोल के लिए नियमों को कुछ हद तक उदार किया गया है:

>>> a, *b, c = range(10) 
>>> a 
0 
>>> b 
[1, 2, 3, 4, 5, 6, 7, 8] 
>>> c 
9 

कि क्या गुइडो लगता है यह भाषा में सुधार होगा पर निर्भर करता है, कि उदारीकरण भी तर्क से कार्य करने के लिए बढ़ाया जा सकता है।

कुछ विचारों के लिए extended iterable unpacking पर चर्चा देखें कि क्यों पाइथन 3 ने नियमों को बदल दिया।

+1

में काम करता है दिलचस्प! धन्यवाद! मेरा मतलब यह नहीं था कि इसे "करना है" लेकिन तर्क के बारे में उत्सुक था। लगता है जैसे यह मनमाने ढंग से हो सकता है। एक कामकाज के लिए, ऐसा लगता है कि 'लागू करें (एफ, ए + [3])' ऐसा करेगा, हालांकि मुझे लगता है कि लागू() को बहिष्कृत किया गया है। – dreeves

+0

स्पष्ट जवाब के लिए फिर से धन्यवाद। इसके बारे में और अधिक जानने के लिए मेरा उत्तर भी देखें, और जिस कामकाज की मैं तलाश कर रहा था। – dreeves

4

f उस क्रम में 3 तर्क (x, y, z की अपेक्षा कर रहा है)।

मान लीजिए L = [1,2]। जब आपपर कॉल करते हैं, तो दृश्यों के पीछे क्या पाइथन करता है, f(3, 1, 2) पर कॉल करना है, वास्तव में L की लंबाई को जानने के बिना।

तो क्या होता है यदि L[1,2,3] था?

फिर, जब आप f(3, *L) फोन, आप f(3,1,2,3), क्योंकि f वास्तव में 3 तर्कों की उम्मीद है जो एक त्रुटि हो जाएगा बुला समाप्त कर देंगे और आप इसे 4.

अब दे दी है, मान लीजिए L=[1,2]1. Look at what happens when you call f`:

>>> f(3,*L) # works fine 
>>> f(*L) # will give you an error when f(1,2) is called; insufficient arguments 

अब, आप अप्रत्यक्ष रूप से जानते हैं जब आप कॉल f(*L, 3) कि 3 z को सौंपा जाएगा, लेकिन अजगर कि पता नहीं है। यह केवल जानता है कि f पर इनपुट के कई तत्व L की सामग्री द्वारा परिभाषित किए जाएंगे। लेकिन चूंकि यह len(L) के मान को नहीं जानता है, इसलिए यह f(*L,3) के तर्कों की सही संख्या के बारे में धारणा नहीं कर सकता है।

हालांकि, f(3,*L) के साथ यह मामला नहीं है। इस मामले में, पायथन जानता है कि पहले के अलावा सभी तर्क L की सामग्री द्वारा परिभाषित किए जाएंगे।

लेकिन यदि आपने तर्क f(x=1, y=2, z=3) नाम दिए हैं, तो नाम से असाइन किए गए तर्क पहले बाध्य होंगे। केवल तभी स्थितित्मक तर्क बाध्य हैं। तो आप f(*L, z=3) करते हैं। उस स्थिति में, z पहले 3 से जुड़ा हुआ है, और फिर, अन्य मान बाध्य हो जाते हैं।

अब दिलचस्प बात है, अगर आप f(*L, y=3) किया था, कि यदि आपको कोई त्रुटि y को आवंटित करने के लिए दो बार (एक बार कीवर्ड के साथ एक बार फिर से स्थितीय के साथ)

आशा की कोशिश कर के लिए देना होगा इस

+0

मुझे लगता है कि मैं इससे असहमत हूं, विशेष रूप से "पायथन उसे नहीं जानता" भाग। जैसा कि रेमंड हेटिंगर कहते हैं, ऐसा लगता है कि यह एक मनमाना प्रतिबंध है। हालांकि उदारीकरण के खिलाफ मैं एक दक्षता तर्क की कल्पना कर सकता हूं। – dreeves

+0

संभव है। मैंने इस प्रश्न को जी + पर साझा किया है, जिसे ग्विडो को टैग किया गया है। चलो देखते हैं कि वह – inspectorG4dget

2

अच्छा लगा। यह tuples के लिए भी काम करता है।

a = (1,2) 
f(*(a+(3,))) 
+0

यह एक गंदे चाल है! –

7

PEP 448 - Additional Unpacking Generalizations के लिए धन्यवाद,

f(*a, 3) 

now accepted syntax starting from Python 3.5 है: अल्पविराम मत भूलना। इसी प्रकार आप डबल-स्टार ** का उपयोग कीवर्ड तर्क के लिए कहीं भी अनपॅकिंग के लिए कर सकते हैं और या तो कई बार उपयोग किया जा सकता है।

-1

यदि आप f(*a, 3) का उपयोग करते हैं तो आप f(*a, z=3) का उपयोग कर सकते हैं, यह नहीं पता कि आपके लिए पैरामीटर को अनपैक कैसे करें 2 पैरामीटर और 2 दूसरा है।

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