2013-04-03 7 views
5

मैं जेनरेटर के अंदर एक ही सूट (रंग) और रैंक के समूह को समूहबद्ध करने की कोशिश कर रहा हूं और उन जेनरेटर को सूची समझ में स्टोर करता हूं।सूची समझ के अंदर एकाधिक जनरेटर बनाना

जिस समाधान के साथ मैं आया था, इस तथ्य को छोड़कर कि सभी जनरेटर में बिल्कुल वही कार्ड होते हैं। कोई विचार क्यों?

यहाँ कोड

deck=range(52) 

gens=[(i for i in deck if i%13==v) for v in range(13)] 

इस आधार पर मैं उदाहरण के लिए उम्मीद करेंगे है:

gens[1].next() 
1 
gens[1].next() 
14 


gens[10].next() 
10 
gens[10].next() 
23 

लेकिन बजाय मैं

gens[1].next() 
12 

gens[1].next() 
25 

gens[1].next() 
38 

और सूची बदले में सभी जनरेटर मिल एक ही परिणाम ..

उत्तर

7

समस्या यह है कि आपके जनरेटर अभिव्यक्ति में v नाम सूची समझ में उस चर v को संदर्भित करता है। इसलिए, जब आपका जेनरेटर अभिव्यक्ति वास्तव में चलता है (जब आप next पर कॉल करते हैं), तो यह v वैरिएबल को देखता है और 12 मान को देखता है, इससे कोई फर्क नहीं पड़ता कि v का मान जेनरेटर बनाया गया था।

एक वैकल्पिक हल:

deck = range(52) 

def select_kth(v): 
    return (i for i in deck if i % 13 == v) 

gens = [select_kth(v) for v in range(13)] 

क्योंकि हम एक समारोह में परिभाषित किया गया, नाम v अपने स्वयं के नामकरण के माहौल में जीने के लिए है और वह भी चारों ओर असंशोधित रहता है।

तुम सच में चाहते हैं तो आपके एक पंक्ति में ऐसा कर सकता है:

gens = [] 
for v in range(13): 
    def gen(): 
     for i in deck: 
      if i%13 == v: 
       yield i 
    gens.append(gen()) 

:

gens = [(lambda v: (i for i in deck if i % 13 == v))(v) for v in range(13)] 
+0

धन्यवाद। यह उत्तर और @abarnert दोनों उत्कृष्ट – jule64

5

आप बराबर नेस्टेड छोरों में इस बारी हैं, तो आप scoping समस्या और अधिक आसानी से देख सकते हैं आप 13 जेनरेटर के साथ समाप्त होते हैं जो सभी v के समान मूल्य से बंधे हैं, 12.

तो, यहां समाधान किसी भी अन्य स्कोपिंग समस्या के समान है: आपको बनाने की आवश्यकता है इसमें v के साथ एक नया दायरा। ऐसा करने का सबसे आसान तरीका एक नया फ़ंक्शन बनाना है:

gens = [(lambda x: (i for i in deck if i%13==x)(v) for v in range(13)] 
+0

हैं, मैं इसे हटाने जा रहा था, क्योंकि यह वास्तव में डगल के समान जवाब है, और वह मेरे सामने एक मिनट पहले आया, लेकिन ... इसमें कुछ अपवित्र हैं, इसलिए मुझे लगता है कि लोग सोचते हैं कि यह लायक है वैसे भी आसपास रहना ... या शायद डगल को सिर्फ नेस्टेड लूप में रूपांतरण की प्रतिलिपि बनाना चाहिए और दोनों जवाबों में एक ही जवाब में सर्वश्रेष्ठ होना चाहिए? – abarnert

+0

आपका उत्तर यह समझाने का एक बिल्कुल अलग तरीका है। मैं इसे छोड़ दूंगा। – William

+0

मुझे आपकी व्याख्या पसंद है और लगता है कि इसे चोरी करने के बजाए इसे अपने आप रखने के लायक है, इसे हटाने की कोई आवश्यकता नहीं है। :) – Dougal

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