Python 如何使用itertools.groupby()按月份和年份对项目进行分组

Python 如何使用itertools.groupby()按月份和年份对项目进行分组,python,django,Python,Django,问题:我正在尝试获取一个排序列表,并根据月份和年份对其进行分组,但无法正确返回分组值 假设这个数据,我们有一个标题和日期/时间列表,它是按datetime排序的 lst=[ {'title':'过去','date_time':datetime.datetime(2020,3,18,0,0)}, {'title':'只是另一个事件','date_time':datetime.datetime(2020,10,1,19,7)}, {'title':'今天上午9点早些时候','date_time':d

问题:我正在尝试获取一个排序列表,并根据月份和年份对其进行分组,但无法正确返回分组值

假设这个数据,我们有一个标题和日期/时间列表,它是按datetime排序的

lst=[
{'title':'过去','date_time':datetime.datetime(2020,3,18,0,0)},
{'title':'只是另一个事件','date_time':datetime.datetime(2020,10,1,19,7)},
{'title':'今天上午9点早些时候','date_time':datetime.datetime(2020,10,21,9,0)},
{'title':'大于.now()','date_time':datetime.datetime(2020,10,21,23,0)},
{'title':'other one','date_time':datetime.datetime(2020,10,30,10,0)},
{'title':'Me testing the latest event','date_time':datetime.datetime(2020,10,30,12,0)},
{'title':'11月18日20','date_time':datetime.datetime(2020,11,18,20,27)},
{'title':'2021年1月18日','date_time':datetime.datetime(2021,1,18,20,0)},
{'title':'3月18日21','date_time':datetime.datetime(2021,3,18,20,0)}
]
然后通过
itertools.groupby()对其进行分组

从itertools导入groupby
def loop_tupe():
措辞={}
对于键,分组在groupby中(lst,key=lambda x:(x['date\u time'].月,x['date\u time'].年)):
对于组中的元素:
附加值(词汇、键、元素)
回音
按月份和年份对其进行分组后,返回的结果如下

{
(3,2020):{'title':'过去','date_time':datetime.datetime(2020,3,18,0,0)},
(10, 2020): [
{'title':'只是另一个事件','date_time':datetime.datetime(2020,10,1,19,7)},
{'title':'今天上午9点早些时候','date_time':datetime.datetime(2020,10,21,9,0)},
{'title':'大于.now()','date_time':datetime.datetime(2020,10,21,23,0)},
{'title':'other one','date_time':datetime.datetime(2020,10,30,10,0)},
{'title':'Me testing the latest event','date_time':datetime.datetime(2020,10,30,12,0)}
],
(112020):{'title':'18nov20','date_time':datetime.datetime(2020,11,18,20,27)},
(12021):{'title':'2021年1月18日','date_time':datetime.datetime(2021,1,18,20,0)},
(3,2021):{'title':'18 Mary 21','date_time':datetime.datetime(2021,3,18,20,0)}
}
它已经被正确分组,但是日期在一个元组中,而我需要它们作为一个“值”,虽然它是这种格式,但我无法像使用原始列表那样循环它

我意识到这与我在
groupby()
中使用匿名函数的方式有关(可能还有返回结果是如何创建的?),但我不确定如何在其中应用月份和年份分组

问题:在保持原始数据格式与列表格式相对相似的同时,如何按月份和年份对原始数据进行分组


编辑

我正在使用的
append\u value
函数

def append_值(dict_obj,key,value):
如果输入dict_obj:
如果不存在(dict_obj[键],列表):
dict_obj[key]=[dict_obj[key]]
dict_obj[键]。追加(值)
其他:
dict_obj[键]=值

编辑2

到目前为止,这是我得到的最接近解决方案

我已经更改了
groupby
中使用的函数,以获取日期时间并将其更改为要比较的字符串。(我把印刷品留在那里以供观想)

def loop_str(到排序):
输出={}
对于键,在groupby中分组(to_sort,key=lambda item:item['date_time']。strftime(“%B%Y”):
对于组中的元素:
附加值(输出、键、元素)
返回输出
这样做会得到这个输出

{
“2020年3月”:{
“title”:“在过去”,“date\u time”:datetime.datetime(2020,3,18,0,0)
},
“2020年10月”:[
{'title':'只是另一个事件','date_time':datetime.datetime(2020,10,1,19,7)},
{'title':'今天上午9点早些时候','date_time':datetime.datetime(2020,10,21,9,0)},
{'title':'大于.now()','date_time':datetime.datetime(2020,10,21,23,0)},
{'title':'other one','date_time':datetime.datetime(2020,10,30,10,0)},
{'title':'Me testing the latest event','date_time':datetime.datetime(2020,10,30,12,0)}
],
“2020年11月”:{
标题:20年11月18日,日期时间:datetime.datetime(2020,11,18,20,27)
},
“2021年1月”:{
“标题”:2021年1月18日,“日期时间”:datetime.datetime(2021,1,18,20,0)
},
“2021年3月”:{
标题:3月18日21日,日期时间:datetime.datetime(2021,3,18,20,0)
}
}

这更接近我所需要的,但是,除非我没有看到一些东西,否则这个输出可能是dicts和list的混合,这将更难在django模板中循环?

您可以将groupby键设置为希望我格式化日期的字符串。然后你可以在听写理解中使用它。如果不断地列出值,则更容易创建数据结构。它可能也会更容易使用

from itertools import groupby
import datetime

lst = [
    {'title': 'in the past','date_time': datetime.datetime(2020, 3, 18, 0, 0)},
    {'title': 'Just another event','date_time': datetime.datetime(2020, 10, 1, 19, 7)},
    {'title': 'earlier today 9am','date_time': datetime.datetime(2020, 10, 21, 9, 0)},
    {'title': 'greater than .now()','date_time': datetime.datetime(2020, 10, 21, 23, 0)},
    {'title': 'another one','date_time': datetime.datetime(2020, 10, 30, 10, 0)},
    {'title': 'Me testing the latest event','date_time': datetime.datetime(2020, 10, 30, 12, 0)},
    {'title': '18 Nov 20','date_time': datetime.datetime(2020, 11, 18, 20, 27)},
    {'title': '18 January 2021','date_time': datetime.datetime(2021, 1, 18, 20, 0)},
    {'title': '18 March 21','date_time': datetime.datetime(2021, 3, 18, 20, 0)}
]

groups = groupby(lst, key=lambda x: (x['date_time'].strftime("%B %Y")))

{k: list(g) for k, g in groups}
结果:

{'March 2020': [{'title': 'in the past',
   'date_time': datetime.datetime(2020, 3, 18, 0, 0)}],
 'October 2020': [{'title': 'Just another event',
   'date_time': datetime.datetime(2020, 10, 1, 19, 7)},
  {'title': 'earlier today 9am',
   'date_time': datetime.datetime(2020, 10, 21, 9, 0)},
  {'title': 'greater than .now()',
   'date_time': datetime.datetime(2020, 10, 21, 23, 0)},
  {'title': 'another one',
   'date_time': datetime.datetime(2020, 10, 30, 10, 0)},
  {'title': 'Me testing the latest event',
   'date_time': datetime.datetime(2020, 10, 30, 12, 0)}],
 'November 2020': [{'title': '18 Nov 20',
   'date_time': datetime.datetime(2020, 11, 18, 20, 27)}],
 'January 2021': [{'title': '18 January 2021',
   'date_time': datetime.datetime(2021, 1, 18, 20, 0)}],
 'March 2021': [{'title': '18 March 21',
   'date_time': datetime.datetime(2021, 3, 18, 20, 0)}]}

现在还不清楚你想要的结果是什么。你想要什么格式?说您希望对项目进行分组,但也希望它与原始列表类似,这实际上没有意义。另外,什么是
append_value()
?因此,它将是日期,因为它们以项目作为其值进行键控,例如[{date:{item}、{item}、{date:{item}],同时将日期作为单个值,而不是分别包含月份和年份的元组。如果将日期作为键,则是哪个日期?您仅按月/年进行分组,这意味着您的分组中的项目将不具有相同的日期。我已更新了我的答案,这将更清楚地解释