【问题标题】:Building a list of months by iterating between two dates in a list (Python)通过在列表中的两个日期之间迭代来构建月份列表(Python)
【发布时间】:2010-07-07 12:34:59
【问题描述】:

我有一个有序(即排序的)列表,其中包含按升序排序(作为日期时间对象)的日期。

我想编写一个函数来遍历这个列表并生成另一个每个月第一个可用日期的列表。

例如,假设我的排序列表包含以下数据:

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”吗?

【问题讨论】:

  • @"# 多重赋值
  • for (curr_date in input_list) 是语法错误; Python 中没有括号。
  • 您的示例数据由字符串组成,在您写的文本中,您有日期时间对象。您也许应该澄清一下,一些解决方案是特定于字符串的,您必须为 datetime 对象稍微重写它们。
  • @Fabian:在撰写问题时,我意识到了“冲突”——但我不太确定如何在文本中表示日期时间对象。 Python 程序员有没有使用约定?

标签: python


【解决方案1】:
>>> 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']

【讨论】:

  • 不错! - 但是,我不明白。小心解释发生了什么,所以我们这些凡人都能理解;)?
  • 查看 itertools.groupby() 文档 (docs.python.org/library/itertools.html#itertools.groupby)。如果您使用此解决方案,请确保列表已排序,否则它将不起作用。
  • @morpheous:我根据月份(日期字符串的前 7 个字符)对日期进行分组,然后从组中选择最小值,形成输出列表的一个元素。
  • @Fabian: list A 需要按月份排序,例如['2001/01/03','2001/01/01','2001/01/05'] 仍然会产生 ['2001/01/01']
  • 我的表述有点过于简单了,列表只需要用相同的键函数排序(或以等价方式生成)即可。
【解决方案2】:

搜索列表是一个 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

【讨论】:

  • @phillip:+1 有用的提示!。顺便说一句,您正在将变量分配给一个-发生了什么? Python中的整数是否重载了逗号运算符?
  • @morpheous:逗号是 Python 中的标准运算符。表达式x, y 的值是一个由xy 组成的元组。在您的原始示例中,[], [] 也只是一个由两个空列表组成的元组。
【解决方案3】:

这是classic 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']

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-11-11
    • 1970-01-01
    • 2023-03-13
    • 2021-12-30
    • 1970-01-01
    • 2010-10-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多