diferencia entre dict (groupby) y groupby

Tengo una lista como esta

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

Llamemos a esta lista como ‘years_list’

Cuando hice grupo por año,

 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) 

Obtuve la salida deseada:

 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'] 

Entonces, cambié ligeramente mi implementación de esta manera,

  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) 

Acabo de agregar un dict, pero la salida es diferente,

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

No pude averiguar por qué. Por favor, ayúdame a encontrar lo que el dictador está haciendo en realidad.

(Python 2.7)

groupby produce pares de (clave, iterador de grupo). Si está iterando el segundo par, el iterador del grupo del primer par ya está consumido, por lo que obtiene una lista vacía.

Intente el siguiente código:

 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 

El problema aquí es que groupby produce, en secuencia, cada clave y un sub-iterador:

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

convertir cada en una lista real antes de almacenarlo, porque la siguiente iteración de groupby restablece el iterador. Si no lo hace, solo queda un iterador útil, de modo que cuando imprime el contenido del diccionario, obtiene una lista no vacía (que utiliza el iterador). Imprimiéndolo una segunda vez, obtendrás listas completamente vacías.

La clave es hacer una lista de los iteradores mientras aún están en buen estado (veo que varios otros me han dado el código de ejemplo, prefiero la variante de falsetru ).

Intente la operación groupby sin transmisión desde 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']} 

De acuerdo con esta respuesta , puedes hacer esto para convertirlo en un dict :

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

Es porque la salida de groupby es un objeto itertools.groupby , que es un tipo de generador, que aparentemente no se puede usar directamente como argumento para el constructor de dict .