Skip to main content
 首页 » 编程设计

python之在 Python 中对连续日期进行分组

2025年05月04日18mayingbao

给定一个日期时间列表:

A= [datetime.datetime(2019, 12, 14, 0, 0), datetime.datetime(2019, 12, 16, 0, 0), 
    datetime.datetime(2019, 12, 24, 0, 0), datetime.datetime(2019, 12, 25, 0, 0), 
    datetime.datetime(2019, 12, 26, 0, 0), datetime.datetime(2019, 12, 27, 0, 0), 
   ] 

我想对相差 1 天的日期时间进行分组,以便输出为:

[datetime.datetime(2019, 12, 14, 0, 0),  
 datetime.datetime(2019, 12, 16, 0, 0),  
 [datetime.datetime(2019, 12, 24, 0, 0), datetime.datetime(2019, 12, 25, 0, 0), 
  datetime.datetime(2019, 12, 26, 0, 0), datetime.datetime(2019, 12, 27, 0, 0)]] 

我已经试过了,但是失败了:

res = [] 
temp = [] 
l = len(A)-1 
for i,v in enumerate(A): 
    if i+1 > l: 
        break 
 
    if abs(v.days() - A[i+1].days()) == 1: 
        temp.append(v) 
    else: 
        if temp: 
            temp.append(v) 
            res.append(temp) 
            temp = [] 
print(res) 

请您参考如下方法:

问题的第一个版本是关于整数的,所以这里首先回答“将差为 1 的整数分组”(请参阅​​下面的日期时间对象)。

您可以使用 itertools.groupby和 itertools.count像这样对它们进行分组:

from itertools import groupby, count 
 
counter = count() 
A= [1,14,24,25,26,27,28,29,30,31] 
out = [list(group) for _, group in groupby(A, key=lambda v:v-next(counter))] 
print(out) 
# [[1], [14], [24, 25, 26, 27, 28, 29, 30, 31]] 

如果您真的希望孤立的值出现在任何列表之外,只需添加:

out = [sublist[0] if len(sublist)==1 else sublist for sublist in out] 
print(out) 
[1, 14, [24, 25, 26, 27, 28, 29, 30, 31]] 

next(counter) 每次被调用都会返回 0, 1, 2...等等。如果值之间的差异为 1,则 v-next(counter) 将保持不变,并且 groupby 对保持不变的项目进行分组。


对于问题的第二个版本,我们可以对具有一天差异的 datetime 对象保持相同的原则:我们减去一个 datetime.timedelta(days=next(counter)) 而不仅仅是 next(counter)。

from itertools import groupby, count 
import datetime 
 
 
A= [datetime.datetime(2019, 12, 14, 0, 0), datetime.datetime(2019, 12, 16, 0, 0), 
    datetime.datetime(2019, 12, 24, 0, 0), datetime.datetime(2019, 12, 25, 0, 0), 
    datetime.datetime(2019, 12, 26, 0, 0), datetime.datetime(2019, 12, 27, 0, 0), 
   ] 
 
counter = count()   
 
out = [list(group) for _, group in groupby(A, key=lambda v:v-datetime.timedelta(days=next(counter)))] 
 
# print(out) 
# [1], [14], [24, 25, 26, 27, 28, 29, 30, 31]] 
 
 
out = [sublist[0] if len(sublist)==1 else sublist for sublist in out] 
print(out) 
 
# [datetime.datetime(2019, 12, 14, 0, 0), datetime.datetime(2019, 12, 16, 0, 0),  
#  [datetime.datetime(2019, 12, 24, 0, 0), datetime.datetime(2019, 12, 25, 0, 0), 
#   datetime.datetime(2019, 12, 26, 0, 0), datetime.datetime(2019, 12, 27, 0, 0)]]