通过在两个日期间迭代构建月份列表(Python)

5 投票
3 回答
4177 浏览
提问于 2025-04-16 00:56

我有一个有序的列表,这个列表里包含了按日期排序的日期(这些日期是日期时间对象),并且是从早到晚排列的。

我想写一个函数,遍历这个列表,生成另一个列表,里面是每个月的第一个可用日期。

比如说,我的排序列表里有以下数据:

A = [
'2001/01/01',
'2001/01/03',
'2001/01/05',
'2001/02/04',
'2001/02/05',
'2001/03/01',
'2001/03/02',
'2001/04/10',
'2001/04/11',
'2001/04/15',
'2001/05/07',
'2001/05/12',
'2001/07/01',
'2001/07/10',
'2002/03/01',
'2002/04/01',
]

返回的列表应该是

B = [
'2001/01/01',
'2001/02/04',
'2001/03/01',
'2001/04/10',
'2001/05/07',
'2001/07/01',
'2002/03/01',
'2002/04/01',
]

我想的逻辑大概是这样的:

def extract_month_first_dates(input_list, start_date, end_date):
    #note: start_date and end_date DEFINITELY exist in the passed in list
    prev_dates, output = [],[]  # <- is this even legal?
    for (curr_date in input_list):
        if ((curr_date < start_date) or (curr_date > end_date)):
            continue

        curr_month = curr_date.date.month
        curr_year = curr_date.date.year
        date_key = "{0}-{1}".format(curr_year, curr_month)
        if (date_key in prev_dates):
            continue
        else:
            output.append(curr_date)
            prev_dates.append(date_key)

    return output

有什么意见或建议吗?- 这个可以改得更“Pythonic”吗?

3 个回答

0

这里有一个简单的解决方案,用的是经典的Python,也就是说没有用到itertools ;) 而且这个代码自解释,非常容易理解。

visited = {}
B = []
for a in A:
    month = a[:7]
    if month not in visited:
        B.append(a)
    visited[month] = 1

print B

输出结果:

['2001/01/01', '2001/02/04', '2001/03/01', '2001/04/10', '2001/05/07', '2001/07/01', '2002/03/01', '2002/04/01']
1

在列表中查找东西的时间复杂度是 O(n),这意味着如果列表里的东西越多,查找的时间就会越长。我觉得你可以简单地检查一下这个关键字是否是新的:

def extract_month_first_dates(input_list):
    output = []
    last_key = None
    for curr_date in input_list:
        date_key = curr_date.date.month, curr_date.date.year  # no string key required
        if date_key != last_key:
            output.append(curr_date)
            last_key = date_key
    return output
7
>>> import itertools
>>> [min(j) for i, j in itertools.groupby(A, key=lambda x: x[:7])]
['2001/01/01', '2001/02/04', '2001/03/01', '2001/04/10', '2001/05/07', '2001/07/01', '2002/03/01', '2002/04/01']

当然可以!请把你想要翻译的内容发给我,我会帮你把它变得更简单易懂。

撰写回答