dict(groupby)和groupby之间的区别

时间:2013-10-01 06:10:45

标签: python python-2.7

我有一个像这样的列表

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

我们可以将此列表称为“years_list”

当我年复一年的时候,

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

我无法找出原因。请帮我看看dict实际上做了什么。

(Python 2.7)

4 个答案:

答案 0 :(得分:8)

groupby产生(key,迭代器 -of-group)对。如果你正在迭代第二对,那么第一对的iterator-of-group已经被消耗了,所以你得到了空列表。

请尝试以下代码:

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 :(得分: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 next 迭代会重置迭代器。如果不这样做,那么只剩下一个有用的迭代器,所以当你打印字典的内容时,你得到一个非空列表(用完了迭代器)。再次打印它,你会得到全空列表。

关键是列出 - 如果迭代器仍然很好(我看到其他几个人打我的示例代码,我更喜欢falsetru's variant)。

答案 2 :(得分:2)

尝试toolz

中的非流媒体groupby操作
$ 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']}

答案 3 :(得分: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构造函数的参数。 / p>