2010-07-08 13 views
5

यह सवाल काफी लंबा होने जा रहा है, इसलिए मैं preemptively माफी माँगता हूँ।अतिरिक्त स्थितित्मक तर्क, अनपॅकिंग तर्क सूचियों या tuples, और विस्तारित iterable unpacking

अजगर में हम निम्नलिखित तीन मामलों में * का उपयोग कर सकते हैं:

मैं जब इस तरह के रूप in this example एक समारोह है कि हम युक्तियों के स्वेच्छाचारी संख्या के साथ प्रतिदेय होना चाहते हैं, को परिभाषित:

def write_multiple_items(file, separator, *args): 
    file.write(separator.join(args)) 

इस मामले में, अतिरिक्त स्थितित्मक तर्क tuple में एकत्र किए जाते हैं।

II। रिवर्स मामला है, जब तर्क या तो एक सूची या एक टपल में पहले से ही कर रहे हैं और हम एक समारोह कॉल ऐसे in this example के रूप में अलग स्थितीय तर्क, की आवश्यकता होती है के लिए उन्हें खोल करना चाहते हैं:

>>> range(3, 6)    # normal call with separate arguments 
[3, 4, 5] 
>>> args = [3, 6] 
>>> range(*args)   # call with arguments unpacked from a list 
[3, 4, 5] 

तृतीय। अजगर 3 के साथ शुरू, * भी विस्तारित सूची या टपल खोल के संदर्भ में, इस तरह के रूप में in this example tuples के लिए प्रयोग किया जाता है:

>>> a, *b, c = range(5) 
>>> b 
[1, 2, 3] 

या सूचियों के लिए:

>>> [a, *b, c] = range(5) 
>>> b 
[1, 2, 3] 

दोनों में मामलों में, अनावश्यक होने वाली सभी वस्तुओं को अनिवार्य रूप से किसी भी अनिवार्य अभिव्यक्ति को असाइन नहीं किया गया है, उन्हें सूची पर असाइन किया गया है।

तो यहाँ सवाल है: मामले में मैं अतिरिक्त args एक टपल में एकत्र कर रहे हैं, जबकि मामले तृतीय में अतिरिक्त आइटम एक सूची को सौंपा है। इस विसंगति से कहां से?

संभव बताए गए परिवर्तनों थे:

[...]

तारांकित लक्ष्य बनाओ एक सूची की एक टपल बजाय केवल स्पष्टीकरण मैं मिल सकता है पीईपी 3132 जो कहता है कि में था । यह एक फ़ंक्शन के * तर्क, के साथ संगत होगा, लेकिन परिणाम को और अधिक कठिन बनाना होगा।

हालांकि

, एक शैक्षणिक दृष्टिकोण से स्थिरता की इस कमी, समस्याग्रस्त विशेष रूप से यह देखते हुए कि अगर तुम परिणाम पर कार्रवाई करने के लिए चाहते थे, तो आप हमेशा कह सकते हैं सूची (ख) (उपरोक्त उदाहरण में ख संभालने एक टपल था)। क्या मैं कुछ भूल रहा हूँ?

उत्तर

7

अजगर में हम निम्नलिखित तीन मामलों में * उपयोग कर सकते हैं:

तुम्हारा मतलब उपसर्ग* ज़ाहिर है, - इन्फ़िक्स* गुणन के लिए प्रयोग किया जाता है।

हालांकि, एक शैक्षणिक नजरिए से स्थिरता की इस कमी समस्याग्रस्त है, विशेष रूप से यह देखते हुए कि यदि आप परिणाम पर कार्रवाई करने के लिए चाहते थे, आप हमेशा कह सकते हैं सूची (ख) (उपरोक्त उदाहरण में यह सोचते हैं ख एक ट्यूपल था)। क्या मुझे कुछ याद आ रही है?

मैं कहूँगा कि डिजाइन समस्या (पुराने और बहुत लंबे दांत में!) इस तथ्य से है कि आप मनमाने ढंग से तर्क आप एक टपल के रूप में उन्हें हो रही है जब एक सूची अधिक होगा प्राप्त कर रहे हैं जब बिना किसी वास्तविक नकारात्मकता के कई मामलों में उपयोगी (अतिरिक्त प्रसंस्करण और स्मृति की छोटी मात्रा को टुपल की बजाय सूची बनाने के लिए आवश्यक हो सकता है, फ़ंक्शन कॉल ओवरहेड के संदर्भ में नगण्य है - या अनुक्रम अनपॅकिंग, उस मामले के लिए; एक सूची बनाने के लिए आवश्यक अतिरिक्त प्रसंस्करण और स्मृति के साथ-साथ एक टुपल वास्तव में अधिक परेशान है)।

बहुत कम है कि आप एक टुपल के साथ कर सकते हैं लेकिन एक सूची नहीं - मूल रूप से, इसे केवल हैशिंग (एक सेट आइटम या dict कुंजी के रूप में उपयोग करने के लिए) - जबकि एक सूची अधिक अतिरिक्त कार्यक्षमता प्रदान करती है, और नहीं इसे बदलने के प्रयोजनों के लिए बस ... count और index जैसी विधियां भी उपयोगी हैं।

+0

उत्तर के लिए धन्यवाद। संक्षेप में जो मैं सुन रहा हूं वह यह है कि ** ** ** को एक सूची देने के लिए डिजाइन किया जाना चाहिए था। –

+0

@Alexandros, यह वास्तव में मेरी राय है - लेकिन निश्चित रूप से हिंडसाइट 20/20 है, और यह निर्णय किया गया था ... मुझे यकीन नहीं है कि, लेकिन यह 11 साल पहले पाइथन 1.5.2 में पहले से ही था। –

8

आप एक को याद किया।

IV। इसके अलावा, पायथन 3 में, तर्क सूची में एक नंगे * स्थितित्मक तर्कों का अंत होता है, जो keyword-only arguments के लिए अनुमति देता है।

def foo(a, b, *, key = None): 
    pass 

यह foo(1, 2, key = 3) नहीं बल्कि foo(1, 2, 3) कहा जा सकता है।

+0

धन्यवाद। हालांकि वास्तव में मेरे प्रश्न का उत्तर नहीं है, लेकिन सभी मामलों को एक धागे में इकट्ठा करना अच्छा लगता है। –

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