dict(groupby)和groupby之间的区别

Joh*_*wyn 6 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']
Run Code Online (Sandbox Code Playgroud)

我们将此列表称为'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)
Run Code Online (Sandbox Code Playgroud)

我得到了所需的输出:

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']
Run Code Online (Sandbox Code Playgroud)

然后,我稍微改变了我的实现,

  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)
Run Code Online (Sandbox Code Playgroud)

我刚刚添加了一个字典,但输出不同,

2003 []
2006 []
2007 []
2004 []
2005 []
2008 []
2009 []
2011 [u'201103']
2010 []
2013 []
2012 []
Run Code Online (Sandbox Code Playgroud)

我找不到原因.请帮我找一下dict究竟在做什么.

(Python 2.7)

fal*_*tru 8

groupby产生对(key,iterator -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
Run Code Online (Sandbox Code Playgroud)

  • @JohnPrawyn,是的.[`itertools._grouper`](http://hg.python.org/cpython/file/70850d6a16ee/Modules/itertoolsmodule.c#l197)对象共享一个迭代器.(`gbo-> it`) (3认同)

tor*_*rek 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>
Run Code Online (Sandbox Code Playgroud)

<itertools._grouper object ...>在将它们存储之前,您需要将每个转换为实际列表,因为一次迭代会groupby重置迭代器.如果不这样做,那么只剩下一个有用的迭代器,所以当你打印字典的内容时,你得到一个非空列表(它用完了迭代器).再次打印,您将获得全空列表.

关键是列出 - 如果它们仍然很好的迭代器(我看到其他几个打败我的示例代码,我更喜欢falsetru的变体).

  • 来自[docs](http://docs.python.org/2/library/itertools.html#itertools.groupby):因为源是共享的,当`groupby()`对象被提前时,前一组是**不再可见**.因此,如果稍后需要该数据,则应将其存储为列表. (2认同)