2011-06-04 21 views
11
>>from itertools import groupby 
>>keyfunc = lambda x : x > 500 
>>obj = dict(groupby(range(1000), keyfunc)) 
>>list(obj[True]) 
[999] 
>>list(obj[False]) 
[] 

सीमा (1000) स्पष्ट रूप से हालत (एक्स> 500) के लिए डिफ़ॉल्ट रूप से क्रमबद्ध किया जाता है।
मैं dict स्थिति (x> 500) द्वारा 0 से 999 तक की संख्या को समूहित करने की अपेक्षा कर रहा था। लेकिन परिणामस्वरूप शब्दकोश केवल 999 था।
अन्य नंबर कहां हैं? क्या कोई यह बता सकता है कि यहां क्या हो रहा है?पायथन समूह व्यवहार?

उत्तर

17

docs से:

लौटे समूह अपने आप में एक इटरेटर iterable अंतर्निहित प्रयोग करती है, groupby() के साथ है। क्योंकि स्रोत साझा किया जाता है, जब groupby() ऑब्जेक्ट उन्नत होता है, तो पिछला समूह अब दिखाई नहीं देता है। तो, अगर है कि डेटा बाद में की जरूरत है, यह के रूप में एक सूची संग्रहीत किया जाना चाहिए [।]

और तुम obj में iterators भंडारण और उन्हें बाद में materializing कर रहे हैं।

In [21]: dict((k, list(g)) for k, g in groupby(range(10), lambda x : x > 5)) 
Out[21]: {False: [0, 1, 2, 3, 4, 5], True: [6, 7, 8, 9]} 
3

बात आप याद कर रहे हैं, कि अपने दिए गए range(1000), अधिक GroupBy-समारोह दोहराता इस प्रकार 1000 मूल्यों लौटने। आप केवल अपने मामले में 999 में अंतिम बचत कर रहे हैं।

dictionary = {} 
keyfunc = lambda x : x > 500 
for k, g in groupby(range(1000), keyfunc): 
    dictionary[k] = list(g) 

तो तुम होगा अपेक्षित आउटपुट मिलता है:: क्या आप, क्या करना है वापसी मूल्यों पर पुनरावृति और उन्हें अपने शब्दकोश में बचाने के लिए है

{False: [0, 1, 2, ...], True: [501, 502, 503, ...]} 

अधिक जानकारी के लिए, पाइथन डॉक्स itertools groupby के बारे में।

7

groupby इटेटरेटर ग्रुपिंग फ़ंक्शन के नतीजे के टुपल्स लौटाता है और एक नया इटरेटर जो उसी "बाहरी" इटरेटर से बंधे हैं groupby ऑपरेटर काम कर रहा है। जब आप इस "आंतरिक" इटरेटर को groupby का उपभोग किए बिना groupby द्वारा लौटाए गए इटरेटर को dict() लागू करते हैं, तो आपके लिए "बाहरी" इटरेटर को अग्रिम करना होगा। आपको यह समझना होगा कि groupby फ़ंक्शन एक अनुक्रम पर कार्य नहीं करता है, यह आपके लिए किसी भी अनुक्रम को इस तरह के अनुक्रम को बदल देता है।

शायद यह कुछ रूपकों और हैंडविंग के साथ बेहतर समझाया गया है। जैसे ही हम एक बाल्टी लाइन बनाते हैं, कृपया साथ ही अनुसरण करें।

इटारेटर को एक कुएं से बाल्टी में पानी खींचने वाले व्यक्ति के रूप में कल्पना करें। उनके पास उपयोग करने के लिए असीमित बाल्टी हैं, लेकिन कुएं सीमित हो सकते हैं। हर बार जब आप इस व्यक्ति को पानी की बाल्टी के लिए पूछते हैं, तो वह पानी के कुएं से एक नई बाल्टी खींच लेगा और इसे आपके पास भेज देगा।

groupby मामले में, आप अपने उभरते बाल्टी श्रृंखला में एक और व्यक्ति डालते हैं। यह व्यक्ति तुरंत बाल्टी पास नहीं करता है। वह आपको निर्देशों का नतीजा देता है जो आपने इसे अन्य व्यक्ति को हर बार बाल्टी मांगने के लिए पास करता है, जिसके बाद आप जो भी पूछ रहे हैं, groupby व्यक्ति के माध्यम से बाल्टी पास करेंगे, जब तक वे निर्देशों के समान परिणाम से मेल खाते हैं। groupby बाल्टी पासर इन बाल्टी को पार करना बंद कर देगा यदि निर्देशों का नतीजा बदल जाता है।तो wellgroupby पर बाल्टी देता है, जो इसे प्रति-समूह व्यक्ति, group A, group B पर भेजता है, और इसी तरह।

आपके उदाहरण में, पानी गिना जाता है, लेकिन कुएं से केवल 1000 बाल्टी तैयार की जा सकती हैं।

  1. आपका dict() कॉल एक बाल्टी के लिए groupby पूछता है: यहाँ क्या होता है जब आप तो dict() कॉल करने के लिए groupby व्यक्ति पार जाते हैं। अब, groupby अच्छी तरह से व्यक्ति से एक बाल्टी मांगता है, बाल्टी को पकड़कर दिए गए निर्देशों के नतीजे को याद करता है। dict() पर वह निर्देशों का परिणाम (False) प्लस एक नया व्यक्ति, group A पास कर देगा। परिणाम कुंजी के रूप में संग्रहीत किया जाता है, और group A व्यक्ति, जो बाल्टी खींचना चाहता है उसे मान के रूप में संग्रहीत किया जाता है। यह व्यक्ति अभी तक बाल्टी मांग रहा है, क्योंकि कोई भी इसे पर नहीं पूछ रहा है।

  2. आपकी dict() कॉल अन्य बाल्टी के लिए groupby पूछता है। groupby में इन निर्देश हैं, और परिणामस्वरूप परिवर्तन के लिए अगली बाल्टी की तलाश में है। यह अभी भी पहली बाल्टी पर पकड़ रहा था, कोई भी इसके लिए नहीं पूछा गया था, इसलिए इस बाल्टी को फेंकता है। इसके बजाए, यह कुएं से अगली बाल्टी मांगता है और उसके निर्देशों का उपयोग करता है। नतीजा पहले जैसा ही है, इसलिए यह भी इस नई बाल्टी को फेंक देता है! अधिक पानी मंजिल पर चला जाता है, और इसलिए अगले 49 9 बाल्टी जाओ। केवल तभी जब संख्या 501 के साथ बाल्टी पारित हो जाती है, तो परिणाम बदलता है, इसलिए अब groupby नए परिणाम, True के साथ निर्देश देने के लिए किसी अन्य व्यक्ति को (group B) निर्देश मिलते हैं, इन दोनों को dict() पर पास करते हैं।

  3. आपकी dict() कॉल स्टोर True एक कुंजी के रूप में, और व्यक्ति group B मूल्य के रूप में स्टोर करता है। group B कुछ भी नहीं करता है, कोई भी इसे पानी के लिए नहीं पूछ रहा है।

  4. आपकी dict() एक और बाल्टी मांगती है। groupby अधिक पानी फैलता है, जब तक कि यह 999 संख्या के साथ बाल्टी नहीं रखता है, और अच्छी तरह से व्यक्ति अपने कंधों को झुकाता है और कहता है कि अब कुएं खाली है। groupbydict() बताता है कि अच्छी तरह खाली है, कोई और बाल्टी नहीं आ रही है, क्या वह कृपया पूछना बंद कर सकता है। यह अभी भी 99 99 के साथ बाल्टी रखता है, क्योंकि इसे कुएं से अगली बाल्टी के लिए जगह नहीं बनाना पड़ता है।

  5. अब आप से संबंधित चीज़ के लिए dict() पूछ रहे हैं, जो व्यक्ति group B है। आप group B से list() पास करते हैं, इसलिए सभी बाल्टी group B प्राप्त कर सकते हैं। group B वापस groupby पर जाता है, जो केवल एक बाल्टी रखता है, 99 99 के साथ बाल्टी रखता है, और इस बाल्टी मैच के निर्देशों का नतीजा group B की तलाश में है। तो यह एक बाल्टी group Blist() को देता है, फिर उसके कंधों को झुकाता है क्योंकि कोई और बाल्टी नहीं होती है, क्योंकि groupby ने उसे बताया।

  6. फिर आप False कुंजी से जुड़े व्यक्ति के लिए dict() पूछें, जो व्यक्ति group A है। अब तक, groupby के पास और कुछ देने के लिए कुछ भी नहीं है, अच्छी तरह से सूखा है और वह 999 बाल्टी पानी के झुंड में खड़ा है जिसमें संख्याएं तैर रही हैं। आपका दूसरा list() कुछ नहीं मिलता है।

इस कहानी का नैतिक? groupby से बात करते समय तत्काल पानी की सभी बाल्टी मांगें, क्योंकि यदि आप नहीं करते हैं तो वह उन्हें सब कुछ फैलाएगा! Iterators fantasia में झाड़ियों की तरह हैं, बिना समझ के पानी को परिश्रम से चलते हैं, और आप बेहतर उम्मीद करते हैं कि आप पानी से बाहर निकलते हैं यदि आप नहीं जानते कि उन्हें कैसे नियंत्रित किया जाए।

>>> from itertools import groupby 
>>> keyfunc = lambda x : x > 5 
>>> obj = dict((k, list(v)) for k, v in groupby(range(10), keyfunc)) 
>>> obj(True) 
[0, 1, 2, 3, 4, 5] 
>>> obj(False) 
[6, 7, 8, 9] 
+0

आप "जादूगर का अपरेंटिस" आपका मतलब है:

यहाँ कोड है कि आप क्या उम्मीद करते हैं (एक छोटा सा कम पानी से बाढ़ को रोकने के) क्या है? या शायद फंतासिया में पानी भी ले जाने वाले ब्रूम हैं? –

+0

@ रेब्लोकॉन मास्क द सॉर्सेरर्स अपरेंटिस [फंतासिया से एक हिस्सा है] (https://en.wikipedia.org/wiki/Fantasia_%281940_film%29#Program)। –

+0

ठीक है, @MartijnPieters धन्यवाद, मुझे यह नहीं पता था। –

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