2012-06-29 23 views
21

मैं कुछ समय के बाद से अजगर उपयोग कर रहा हूँ और मैं कोड करने के लिए "pythonic" जिस तरह से खोज कर रहा हूँ। मैं अपने कोड में बहुत सारे टुपल्स का उपयोग कर रहा हूं, उनमें से अधिकांश ध्रुवीय या कार्टेशियन स्थितियां हैं।tuples पठनीयता: [0,0] बनाम (0,0)

मुझे लगने इस लेखन:

window.set_pos([18,8]) 
बजाय इस बात का

:

window.set_pos((18,8)) 

डबल कोष्ठक मैं पढ़ने के लिए मुश्किल पाया से छुटकारा पाने के।

ऐसा लगता है कि पाइथन स्वचालित रूप से सूची से टाइप करने के लिए प्रकार का रूपांतरण कर रहा है, क्योंकि मेरा कोड ठीक से काम करता है।

लेकिन क्या यह कोड का एक अच्छा तरीका है? क्या आपके पास कोई प्रस्तुति युक्ति है जिसे मैं पठनीय कोड लिखने के लिए उपयोग कर सकता हूं?

अपने निश्चित रूप से शिक्षाप्रद जवाब के लिए अग्रिम धन्यवाद।

+0

मुझे जिस तरह से आपने लिखा है उसे पसंद है, और अधिक अच्छी तरह परिभाषित आईएमओ लगता है। – jamylak

+9

पायथन "सूची से टुपल में प्रकार का रूपांतरण नहीं कर रहा है"। यह [बतख टाइपिंग] है (http://en.wikipedia.org/wiki/Duck_typing) कार्रवाई में: संभावित रूप से 'window.set_pos' को दो आइटमों का अनुक्रम की आवश्यकता होती है, लेकिन जरूरी नहीं कि 2-'ऊपरी' (मैं संभवतः कहता हूं चूंकि मुझे नहीं पता कि 'window.set_pos' कहां से है या यह क्या करता है)। – Chris

+9

फ़ंक्शन को 2-टुपल के बजाय दो तर्क लेने के लिए लिखें। –

उत्तर

25

मैं हर जगह सूचियों के पक्ष में tuples eschew का निर्णय लेने के लिए सावधान रहना होगा। क्या आपने कभी dis मॉड्यूल का उपयोग किया है? देखो क्या अजगर बाईटकोड स्तर पर कर रही है जब आप एक टपल बनाने एक सूची छंद बनाने:

>>> def f(): 
...  x = [1,2,3,4,5,6,7] 
...  return x 
... 
>>> def g(): 
...  x = (1,2,3,4,5,6,7) 
...  return x 
... 
>>> import dis 
>>> dis.dis(f) 
    2   0 LOAD_CONST    1 (1) 
       3 LOAD_CONST    2 (2) 
       6 LOAD_CONST    3 (3) 
       9 LOAD_CONST    4 (4) 
      12 LOAD_CONST    5 (5) 
      15 LOAD_CONST    6 (6) 
      18 LOAD_CONST    7 (7) 
      21 BUILD_LIST    7 
      24 STORE_FAST    0 (x) 

    3   27 LOAD_FAST    0 (x) 
      30 RETURN_VALUE  
>>> 
>>> 
>>> dis.dis(g) 
    2   0 LOAD_CONST    8 ((1, 2, 3, 4, 5, 6, 7)) 
       3 STORE_FAST    0 (x) 

    3   6 LOAD_FAST    0 (x) 
       9 RETURN_VALUE 

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

+1

बहुत बहुत धन्यवाद, आपने मुझे विश्वास दिलाया! मुझे वास्तव में प्रदर्शन की परवाह है क्योंकि मेरा आवेदन एक जीयूआई नहीं है बल्कि ग्राफिकल जीयूआई वाला एक गेम है। आप बाइटकोड विस्तृत उत्तर पृष्ठभूमि में क्या हो रहा है यह समझने में वास्तव में सहायक है (मुझे डी मॉड्यूल नहीं पता था)। –

+1

मैंने बस दो कार्यों का समय दिया: सूची संस्करण लगभग लेता है। ट्यूपल संस्करण की तुलना में समय को दोगुना करें (10 एमओओ कॉल के लिए 2.1 बनाम 0.9 सेकंड)। दो-तत्व संग्रहों के लिए, हालांकि, अंतर छोटा है: 1.6 बनाम 0.9 सेकंड। –

+2

आह, दाएं - मैं भूल गया था कि ट्यूपल अक्षर [folded] हैं (http://stackoverflow.com/a/8068248/577088)। यदि आप शाब्दिक उत्तीर्ण हो रहे हैं (और चर से बने टुपल्स नहीं), तो इससे बड़ा अंतर हो सकता है। – senderle

0

आप तथ्य यह है कि अपने पैरामीटर एक टपल है तनाव करना चाहते हैं, तो आप स्पष्ट रूप से परिवर्तित कर सकते हैं:

window.set_pot(tuple([18, 18])) 
+4

यह बहुत खराब दिखता है। – jamylak

4

IMO [18,8] से अधिक (18,8) का उपयोग करने का लाभ यह है कि केवल एक टपल वस्तु अपरिवर्तनीय है और आप कर सकते हैं है सुनिश्चित करें कि यह पारित किए गए फ़ंक्शन के अंदर नहीं बदला जाएगा, जबकि [18,8] आसानी से बदला जा सकता है।

4

पायथन सूची से किसी भी स्वचालित रूपांतरण को टुपल नहीं कर रहा है, जब तक कि set_pos विधि स्पष्ट रूप से ऐसा न करे। tuple और सूची में बहुत ही समान प्रोटोकॉल हैं, इसलिए वे उस प्रोटोकॉल के भीतर अंतर-परिवर्तनीय होते हैं। आप अभी भी चीजों को तोड़ सकते हैं, विशेष रूप से क्योंकि ट्यूपल एक अपरिवर्तनीय है जिसे धोया जा सकता है, और एक सूची नहीं है।

आपके प्रश्न का उत्तर के लिए, बस लिखने

window.set_pos((18,18)) 

उचित रिक्त स्थान शैली कोडिंग के साथ चमत्कार कर सकते हैं।

+4

पीईपी -8 सलाह नहीं देता है: http://www.python.org/dev/peps/pep-0008/#pet-peeves – jamylak

+1

@jamylak: सहमत हैं, और मैं पीईपी सुझाव से सहमत हूं, लेकिन यह एक विशेष है मामला जो अपवाद के लायक हो सकता है। –

+0

@jamylak यह भाषा द्वारा लागू नहीं है, जिसका अर्थ है कि यह सिर्फ एक कोडिंग शैली है जिसे पाइथन के लेखक का शौक होना चाहिए। यह कोडिंग शैली की सभी-अंत-अंत नहीं है, और इसे कभी भी नहीं लिया जाना चाहिए। बस उन्हें _ दिशानिर्देश दिशानिर्देशों के रूप में देखें, और जब वे पठनीयता को नुकसान पहुंचाते हैं तो उन्हें तोड़ने के लिए तैयार रहें - जैसे कि इस मामले में। – Izkata

12

आप कहते हैं कि

ऐसा नहीं है कि अजगर स्वचालित रूप से

कि संदिग्ध है टपल के लिए सूची से जैसे रूपांतरण कर रही है लगता है। चूंकि सूचियां और टुपल्स sequence types दोनों हैं, इसलिए वे दोनों एक ही व्यवहार को लागू करते हैं, और जो भी जीयूआई लाइब्रेरी आप उपयोग कर रहे हैं उसे किसी भी सूची-केवल व्यवहार की आवश्यकता नहीं है।

>>> sys.getsizeof((1, 2)) 
72 
>>> sys.getsizeof([1, 2]) 
88 

और कुछ चीजों को tuples की तुलना में धीमी हो सकती है::

यह कई मामलों में ऐसा करते हैं, लेकिन ध्यान रखें कि सूचियों tuples से थोड़ा अधिक स्थान ले करते शायद ठीक है

>>> lst, tup = [1, 2], (1, 2) 
>>> def unpack(x): 
...  a, b = x 
...  
>>> %timeit unpack(tup) 
10000000 loops, best of 3: 163 ns per loop 
>>> %timeit unpack(lst) 
10000000 loops, best of 3: 172 ns per loop 

ये बहुत छोटे मतभेद है कि कोई फर्क नहीं होगा जब तक आप बहुत बड़े पैमाने तक पहुँचने कर रहे हैं - अरबों कॉल की में के रूप में - रों o व्यापार बंद इसके लायक हो सकता है।

फिर भी, मुझे नहीं लगता कि लोग अक्सर ऐसा करते हैं। यह एक अच्छी पठनीयता चाल की तरह लगता है, लेकिन कुछ परिस्थितियों में इसका अप्रत्याशित परिणाम हो सकता है। उदाहरण के लिए, यदि आप एक सूची उत्तीर्ण करते हैं जिसे आप बाद में उपयोग करना चाहते हैं, तो आपको सावधान रहना होगा कि इसे फ़ंक्शन के अंदर संशोधित न करें। अंत में, J.F. Sebastian सही रूप से इंगित करता है, tuples और सूचियां का अर्थ थोड़ा अलग चीजें हैं; अपरंपरागत तरीकों से उनका उपयोग करने से आप जो पठनीयता बढ़ाने की बढ़ावा दे सकते हैं उसे अस्वीकार कर सकते हैं।

+0

आपके सटीक उत्तर के लिए धन्यवाद! मुझे पता है कि यह थोड़ा अजीब लगता है, लेकिन मैं केवल पठनीयता उद्देश्य के लिए एक अनुचित वस्तु का उपयोग करने के विचार से रोमांचित हूं। मेरी "set_pos" विधि केवल दो चरों में तर्क को अनपैक करती है, लेकिन अधिकांश समय लूप के अंदर उपयोग की जाती है और मुझे प्रदर्शन समस्याओं की परवाह है। क्या 14 एनएस बहुत मायने रखते हैं? –

+0

नहीं, आपकी खिड़की की स्थिति निर्धारित करने के लिए 14ns कोई फर्क नहीं पड़ता। –

8

मुझे गंभीरता से संदेह है कि टुपल्स बनाम सूचियां आपके मामले में प्रदर्शन में उल्लेखनीय अंतर बनाती हैं। माइक्रो-ऑप्टिमाइज़ेशन न करें जब तक कि आपका प्रोफाइलर ऐसा नहीं कहता। पठनीयता एक प्राथमिकता है।

list और tuplesequence types दोनों हैं।

अर्थात् टुपल्स बेहतर हो सकता है (Tuples have structure, lists have order देखें)। स्थिति एक एकल वस्तु है जिसमें x, y विशेषताएँ हैं।

दृश्यमान सूचियां इस मामले में पढ़ने में आसान हो सकती हैं।

जो भी आप चुनते हैं लगातार हो।

window.pos = 18, 8 

इसे लागू करने के लिए एक संभव तरीका pos एक property बनाने के लिए और एक सेटर के रूप में set_pos() बाध्य करने के लिए है:

कि क्या चेक window निम्नलिखित का समर्थन करता है।

+2

+1 टुपल्स बनाम सूचियों के अर्थशास्त्र के लिए +1, जो लगभग हमेशा निर्णय लेने वाले कारक का उपयोग करना चाहिए। – FogleBird