2008-11-22 21 views
46

कुछ स्थितियों में सूची समझ उपयोगी हो सकती है, लेकिन वे पढ़ने के लिए भी भयानक हो सकती हैं .. थोड़ा अतिरंजित उदाहरण के रूप में, आप निम्न को कैसे इंडेंट करेंगे?पायथन सूची-समझ को कैसे इंडेंट करें?

allUuids = [x.id for x in self.db.query(schema.allPostsUuid).execute(timeout = 20) if x.type == "post" and x.deleted is not False] 

उत्तर

55

यह इस बात पर निर्भर करता है कि वे कब तक हैं। मैं उन्हें इस तरह की संरचना करता हूं:

[x.id for x 
in self.db.query(schema.allPostsUuid).execute(timeout=20) 
if x.type == 'post' 
    and x.deleted is not False 
    and ... 
    and ...] 

इस तरह प्रत्येक अभिव्यक्ति की अपनी रेखा होती है।

किसी भी लाइन बहुत बड़ा हो जाता है मैं एक लैम्ब्डा या अभिव्यक्ति में इसे बाहर निकालने के लिए पसंद करते हैं:

transform = lambda x: x.id 
results = self.db.query(schema.allPostsUuid).execute(timeout=20) 
condition = lambda x: x.deleted is not False and ... and ... 
[transform(x) for x in results if condition(x)] 

और फिर अगर एक लैम्ब्डा बहुत लंबा यह एक समारोह के लिए प्रोत्साहित किया जाता है हो जाता है।

+3

ये समकक्ष नहीं हैं - सूची समझ कई गुना तेज है, क्योंकि इसे किसी फ़ंक्शन लुकअप करने की आवश्यकता नहीं है। उचित अनुवाद लूप के लिए उपयोग करेगा। – Claudiu

+2

प्रदर्शन हिट के अलावा, यह एक बहुत ही पठनीय उदाहरण है! – Geo

+1

लूप फंक्शन लुकअप को कैसे रोकेंगे? यह भी ध्यान रखें कि सूची समझ में लूप सी में लागू किया गया है, और इसलिए सादे से तेज है। – orestis

1

कैसे के बारे में:

allUuids = [x.id for x in self.db.query(schema.allPostsUuid).execute(timeout = 20) 
        if (x.type == "post" and x.deleted is not False)] 

आम तौर पर, लंबी लाइनों चर में पूर्व कंप्यूटिंग subexpressions से बचा जा सकता है, जो एक मामूली प्रदर्शन लागत जोड़ सकते हैं:

query_ids = self.db.query(schema.allPostsUuid).execute(timeout = 20) 
allUuids = [x.id for x in query_ids 
        if (x.type == "post" and x.deleted is not False)] 

वैसे , 'is not False' प्रकार की अनावश्यक नहीं है? क्या आप किसी और के बीच अंतर करने के बारे में चिंतित हैं? क्योंकि अन्यथा, यह केवल स्थिति को छोड़ने के लिए पर्याप्त है: i f (x.type == "post" and x.deleted)

+0

मैं दूसरा यह है कि:

ऐसे ही और अधिक जटिल comprehensions मैं yield के साथ एक जनरेटर का उपयोग सुझाव देंगे लिए

। आम तौर पर सभी भाषाओं में 80 से अधिक वर्णों की रेखाओं से बचा जाना चाहिए। –

+0

सहमत हैं, लेकिन पायथन के वाक्यविन्यास नियम अक्सर लंबी लाइनों को प्रोत्साहित/बल देते हैं। सामान्य रूप से इसका व्हाइटस्पेस हैंडलिंग भाषा के बारे में मेरी एकमात्र शिकायत है। –

+0

ध्यान से चुने गए चर, और ब्रांडेसिस या ब्रैकेट के साथ विभाजित लाइनों के साथ, मुझे कभी भी लंबी लाइनों का सहारा लेना पड़ता था (समस्याएं अक्सर tem.long_foo.very_long_bar.baz (....) से अस्थायी का उपयोग करने से बचती हैं) –

5

मेरे लिए यह बहुत अधिक है। हो सकता है कि यह सिर्फ एक भयानक उदाहरण है, क्योंकि "टाइप" और "हटाया गया" स्पष्ट रूप से डीबी क्वेरी का हिस्सा होगा।

मुझे लगता है कि अगर एक सूची समझ कई लाइनों में फैली हुई है तो शायद यह एक सूची समझ नहीं होनी चाहिए। ऐसा कहकर, मैं आम तौर पर इस चीज़ को "अगर" अन्य लोगों की तरह यहां विभाजित करता हूं और यहां जवाब दूंगा।

37

मैं कहां से काम करते हैं, हमारे कोडिंग दिशा निर्देशों हमें इस तरह कुछ करना होगा:

all_posts_uuid_query = self.db.query(schema.allPostsUuid) 
all_posts_uuid_list = all_posts_uuid_query.execute(timeout=20) 
all_uuid_list = [ 
    x.id 
    for x in all_posts_uuid_list 
    if (
     x.type == "post" 
     and 
     not x.deleted # <-- if you don't care about NULLs/None 
    ) 
] 
+0

यह काफी सुंदर है। –

+0

इस तरह मैं इसे करता हूं – orip

5
allUuids = [x.id 
      for x in self.db.query(schema.allPostsUuid).execute(timeout = 20) 
      if x.type == "post" and x.deleted is not False] 
5

आपको लगता है कि के लिए एक सूची समझ का उपयोग नहीं करना चाहिए।

सूची समझ एक शानदार विशेषता है, लेकिन वे शॉर्टकट होने के लिए हैं, नियमित कोड नहीं।

allUuids = [] 
for x in self.db.query(schema.allPostsUuid).execute(timeout = 20) : 
    if x.type == "post" and x.deleted is not False : 
     allUuids.append(x.id) 

वास्तव में समान व्यवहार, और अधिक पठनीय:

इतने लंबे स्निपेट के लिए, आप साधारण ब्लॉक का उपयोग करना चाहिए। Guido आपको गर्व होगा :-)

+0

यह एक छोटा सा धीमा है, क्योंकि आपको चरण – Claudiu

+0

द्वारा सरणी चरण बनाना है, मुझे लगता है कि सूची समझ हुड के नीचे बिल्कुल वही है। ऐसा इसलिए नहीं है क्योंकि यह एक पंक्ति अभिव्यक्ति है कि यह एक बार ऑपरेशन है ... –

+1

ई-स्टेटिस: फ़ंक्शन एक जैसा है, लेकिन सूची की समझें काफी तेज हो सकती हैं – orip

0

यदि आप एक समझ पर सेट हैं orestis's answer अच्छा है।

allUuids = list(self.get_all_uuids()) 


def get_all_uuids(self): 
    for x in self.db.query(schema.allPostsUuid).execute(timeout = 20): 
     if x.type == "post" and x.deleted is not False: 
      yield x.id 
संबंधित मुद्दे