2013-10-01 17 views
5

मैं, 'years_list'अंतर

जब मैं GroupBy साल किया था के रूप में इस सूची फोन की सुविधा देता है इस

[u'201003', u'200403', u'200803', u'200503', u'201303', 
u'200903', u'200603', u'201203', u'200303', u'200703', u'201103'] 

की तरह एक सूची है

group_by_yrs_list = groupby(years_list, key = lambda year_month: year_month[:-2]) 
for k,v in group_by_yrs_list: 
    print k, list(v) 

मैं वांछित आउटपुट मिला:

2010 [u'201003'] 
2004 [u'200403'] 
2008 [u'200803'] 
2005 [u'200503'] 
2013 [u'201303'] 
2009 [u'200903'] 
2006 [u'200603'] 
2012 [u'201203'] 
2003 [u'200303'] 
2007 [u'200703'] 
2011 [u'201103'] 

फिर, मैं हल्के से बदल दिया इस तरह मेरी कार्यान्वयन,

group_by_yrs_list = dict(groupby(years_list, key = lambda year_month: year_month[:-2])) 
    for k,v in group_by_yrs_list.items(): 
    print k, list(v) 

मैं सिर्फ एक dict को शामिल किया है, लेकिन उत्पादन, अलग है

2003 [] 
2006 [] 
2007 [] 
2004 [] 
2005 [] 
2008 [] 
2009 [] 
2011 [u'201103'] 
2010 [] 
2013 [] 
2012 [] 

मैं बाहर क्यों नहीं पा सके। कृपया यह जानने में मेरी सहायता करें कि वास्तव में क्या कर रहा है।

(अजगर 2,7)

+0

गैर स्ट्रीमिंग groupby आपरेशन की कोशिश करो। लेकिन क्यों केवल एक सूची खाली नहीं है, यह अजीब – TerryA

+1

@ हैड्रो: falstru द्वारा जवाब आपको प्रबुद्ध करना चाहिए। – justhalf

+0

@justhalf ओह बिल्कुल! – TerryA

उत्तर

8

groupby (कुंजी, इटरेटर के- समूह) के जोड़े अर्जित करता है। यदि आप दूसरी जोड़ी को पुन: सक्रिय कर रहे हैं, तो पहली जोड़ी के इटरेटर-समूह को पहले से ही उपभोग किया गया है, इसलिए आपको खाली सूची मिलती है।

कोशिश निम्नलिखित कोड:

group_by_yrs_list = {year:list(grp) for year, grp in groupby(years_list, key=lambda year_month: year_month[:-2])} 
for k, v in group_by_yrs_list.items(): 
    print k, v 
+1

जिसका अर्थ है कि सभी समूहीकृत मान एक एकल पुनरावर्तक को संदर्भित करते हैं। क्या मैं सही हूँ ? –

+3

@ जॉनप्रविन, हां। ['itertools._grouper'] (http://hg.python.org/cpython/file/70850d6a16ee/Modules/itertoolsmodule.c#l197) ऑब्जेक्ट्स एक एकल इटरेटर साझा करते हैं। ('gbo-> it') – falsetru

1

this answer के अनुसार, आप यह कर सकते हैं इसे में परिवर्तित करने के लिए एक dict:

group_by_yrs_list = dict((k,list(v)) for k,v in groupby(years_list, key=lambda x: x[:4])) 

क्योंकि groupby के उत्पादन में एक itertools.groupby वस्तु है, जो है यह एक प्रकार का जनरेटर, जो स्पष्ट रूप से dict कन्स्ट्रक्टर के तर्क के रूप में सीधे उपयोग नहीं किया जा सकता है।

6

समस्या यहाँ है कि groupby पैदावार, अनुक्रम में, प्रत्येक कुंजी और एक उप इटरेटर:

>>> for k, v in groupby(years_list, key = lambda year_month: year_month[:-2]): 
... print k, v 
2010 <itertools._grouper object at 0x801c68950> 
2004 <itertools._grouper object at 0x801bb3a90> 
2008 <itertools._grouper object at 0x801c68950> 
2005 <itertools._grouper object at 0x801bb3a90> 
2013 <itertools._grouper object at 0x801c68950> 
2009 <itertools._grouper object at 0x801bb3a90> 
2006 <itertools._grouper object at 0x801c68950> 
2012 <itertools._grouper object at 0x801bb3a90> 
2003 <itertools._grouper object at 0x801c68950> 
2007 <itertools._grouper object at 0x801bb3a90> 
2011 <itertools._grouper object at 0x801c68950> 

आप इसे दूर भंडारण से पहले एक वास्तविक सूची में प्रत्येक <itertools._grouper object ...> चालू करने की आवश्यकता है, क्योंकि अगलेgroupby का पुनरावृत्ति इटरेटर को रीसेट करता है। यदि आप नहीं करते हैं, तो केवल एक उपयोगी इटरेटर शेष है, इसलिए जब आप शब्दकोश की सामग्री प्रिंट करते हैं, तो आपको एक गैर-खाली सूची मिलती है (जो इटरेटर का उपयोग करती है)। इसे दूसरी बार प्रिंट करना, आपको सभी खाली सूचियां मिलेंगी।

कुंजी की सूची है- अगर वे अभी भी अच्छे हैं तो इटरेटर (मुझे लगता है कि कई अन्य मुझे उदाहरण कोड पर हराते हैं, मैं falsetru's variant पसंद करता हूं)।

+2

[डॉक्स] से (http://docs.python.org/2/library/itertools.html#itertools.groupby): क्योंकि स्रोत साझा किया जाता है, जब 'groupby()' ऑब्जेक्ट उन्नत है, पिछला समूह ** अब दिखाई नहीं दे रहा है **। इसलिए, यदि उस डेटा को बाद में जरूरी है, तो इसे एक सूची के रूप में संग्रहीत किया जाना चाहिए। –

+0

हाँ, मूल रूप से एक ही कथन, लेकिन कम और अधिक सटीक (मैं बिल्कुल नहीं कहता * क्यों * पुराना ' बेकार हो जाता है), लेकिन मुझे संदेह है कि संस्करण उड़ सकता है ओपी का सिर :-) – torek

+0

आपका उत्तर पर्याप्त स्पष्ट है, बस दस्तावेज़ों में कुछ संदर्भ जोड़ना चाहता था। –

2

याद रखें कि शब्दकोशों आदेश की जरूरत नहीं है से toolz

$ pip install toolz 
$ ipython 

In [1]: from toolz import groupby 

In [2]: years_list = [u'201003', u'200403', u'200803', u'200503', u'201303', 
    ...: u'200903', u'200603', u'201203', u'200303', u'200703', u'201103'] 

In [3]: get_year = lambda year_month: year_month[:-2] 

In [4]: groupby(get_year, years_list) 
Out[4]: 
{u'2003': [u'200303'], 
u'2004': [u'200403'], 
u'2005': [u'200503'], 
u'2006': [u'200603'], 
u'2007': [u'200703'], 
u'2008': [u'200803'], 
u'2009': [u'200903'], 
u'2010': [u'201003'], 
u'2011': [u'201103'], 
u'2012': [u'201203'], 
u'2013': [u'201303']}