Python:将('周一','周二','周三')转换为'周一到周三'

Bel*_*dez 6 python datetime date

我得到了一周中的一天.我想做的Python代码:

def week_days_to_string(week_days):
    """
    >>> week_days_to_string(('Sunday', 'Monday', 'Tuesday'))
    'Sunday to Tuesday'
    >>> week_days_to_string(('Monday', 'Wednesday'))
    'Monday and Wednesday'
    >>> week_days_to_string(('Sunday', 'Wednesday', 'Thursday'))
    'Sunday, Wednesday, Thursday'
    """
    if len(week_days) == 2:
       return '%s and %s' % weekdays
    elif week_days_consecutive(week_days):
       return '%s to %s' % (week_days[0], week_days[-1])
    return ', '.join(week_days)
Run Code Online (Sandbox Code Playgroud)

我只需要week_days_consecutive功能(困难部分).

任何想法我怎么能做到这一点?

澄清:

我的措辞和例子引起了一些混乱.我不仅希望将此功能限制在工作周.我想考虑一周中的所有日子(S,M,T,W,T,F).我很抱歉昨晚不清楚这一点.编辑了问题的正文,使其更加清晰.

编辑:把一些扳手扔进去

环绕顺序:

>>> week_days_to_string(('Sunday', 'Monday', 'Tuesday', 'Saturday'))
'Saturday to Tuesday'
Run Code Online (Sandbox Code Playgroud)

并且,根据@ user470379和可选:

>>> week_days_to_string(('Monday, 'Wednesday', 'Thursday', 'Friday'))
'Monday, Wednesday to Friday'
Run Code Online (Sandbox Code Playgroud)

Ste*_*eve 5

我会通过以下方式解决这个问题

  • 创建一个dict映射日名称到它们的顺序索引
  • 将输入日名称转换为顺序索引
  • 查看结果输入索引并询问它们是否是连续的

以下是如何使用calendar.day_name,range以及一些用于理解的方法:

day_indexes = {name:i for i, name in enumerate(calendar.day_name)}
def weekdays_consecutive(days):
    indexes = [day_indexes[d] for d in days]
    expected = range(indexes[0], indexes[-1] + 1)
    return indexes == expected
Run Code Online (Sandbox Code Playgroud)

其他一些选项,取决于您的需求:

  • 如果你需要Python <2.7,而不是dict理解,你可以使用:

    day_indexes = dict((name, i) for i, name in enumerate(calendar.day_name))
    
    Run Code Online (Sandbox Code Playgroud)
  • 如果您不想允许星期六和星期日,请在最后两天修剪:

    day_indexes = ... calendar.day_name[:-2] ...
    
    Run Code Online (Sandbox Code Playgroud)
  • 如果你需要在星期天之后回头,最简单的方法就是检查每个项目是否比上一个项目多一个,但是在模7中工作:

    def weekdays_consecutive(days):
        indexes = [day_indexes[d] for d in days]
        return all(indexes[i + 1] % 7 == (indexes[i] + 1) % 7
                   for i in range(len(indexes) - 1))
    
    Run Code Online (Sandbox Code Playgroud)

更新:对于扩展的问题,我仍然坚持他们的日期索引dict,但相反,我会:

  • 查找连续日期停止的所有索引
  • 如有必要,请将日期包裹起来以获得尽可能长的日期
  • 将日期分为连续跨度

这是执行此操作的代码:

def weekdays_to_string(days):
    # convert days to indexes
    day_indexes = {name:i for i, name in enumerate(calendar.day_name)}
    indexes = [day_indexes[d] for d in days]

    # find the places where sequential days end
    ends = [i + 1
            for i in range(len(indexes))
            if (indexes[(i + 1) % len(indexes)]) % 7 !=
               (indexes[(i) % len(indexes)] + 1) % 7]

    # wrap the days if necessary to get longest possible sequences
    split = ends[-1]
    if split != len(days):
        days = days[split:] + days[:split]
        ends = [len(days) - split + end for end in ends]

    # group the days in sequential spans
    spans = [days[begin:end] for begin, end in zip([0] + ends, ends)]

    # format as requested, with "to", "and", commas, etc.
    words = []
    for span in spans:
        if len(span) < 3:
            words.extend(span)
        else:
            words.append("%s to %s" % (span[0], span[-1]))
    if len(days) == 1:
        return words[0]
    elif len(days) == 2:
        return "%s and %s" % tuple(words)
    else:
        return ", ".join(words)
Run Code Online (Sandbox Code Playgroud)

您也可以尝试以下方法而不是最后一个if/elif/else方块来获取最后两个项目之间的"和"以及其他所有项之间的逗号:

    if len(words) == 1:
        return words[0]
    else:
        return "%s and %s" % (", ".join(words[:-1]), words[-1])
Run Code Online (Sandbox Code Playgroud)

这与规格略有不同,但在我看来更漂亮.