【问题标题】:Return a list of weekdays, starting with given weekday返回一个工作日列表,从给定的工作日开始
【发布时间】:2011-05-04 05:22:25
【问题描述】:

我的任务是定义一个函数weekdays(weekday),它返回一个工作日列表,从给定的工作日开始。它应该像这样工作:

>>> weekdays('Wednesday')
['Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday', 'Monday', 'Tuesday']

到目前为止,我已经想出了这个:

def weekdays(weekday):
    days = ('Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday',
            'Sunday')
    result = ""
    for day in days:
        if day == weekday:
            result += day
    return result

但这仅打印输入日期:

>>> weekdays("Sunday")
'Sunday'

我做错了什么?

【问题讨论】:

    标签: python calendar weekday


    【解决方案1】:

    下面的代码将根据您想要的 X 天生成一个列表,如果您想要生成返回的天数列表,请将 [减号改为加号]

    import datetime
    numdays = 7
    base = datetime.date.today()
    date_list = [base + datetime.timedelta(days=x) for x in range(numdays)]
    date_list_with_dayname = ["%s, %s" % ((base + datetime.timedelta(days=x)).strftime("%A"),  base + datetime.timedelta(days=x)) for x in range(numdays)]
    

    【讨论】:

      【解决方案2】:

      您的 result 变量是 string 而不是 list 对象。此外,它只会更新一次,即当它等于传递的weekday 参数时。

      这是一个实现:

      import calendar
      
      def weekdays(weekday):
          days = [day for day in calendar.day_name]
          for day in days:
              days.insert(0, days.pop())    # add last day as new first day of list           
              if days[0] == weekday:        # if new first day same as weekday then all done
                  break       
          return days
      

      示例输出:

      >>> weekdays("Wednesday")
      ['Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday', 'Monday', 'Tuesday']
      >>> weekdays("Friday")
      ['Friday', 'Saturday', 'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday']
      >>> weekdays("Tuesday")
      ['Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday', 'Monday']
      

      【讨论】:

        【解决方案3】:

        您的代码仅返回一天名称的原因是,weekday 永远不会匹配 days 元组中的多个字符串,因此不会添加其后的一周中的任何一天(也不换行围绕在它之前的那些)。即使它以某种方式发生,它仍然会将它们全部作为一个长字符串返回,因为您将 result 初始化为一个空字符串,而不是一个空的 list

        这里有一个解决方案,它使用datetime 模块来创建以当前语言环境的语言“星期一”开头的所有工作日名称的列表。然后使用该列表以返回的所需顺序创建另一个名称列表。它通过在原始列表中找到指定日期的索引然后将相对于该索引的两个切片拼接在一起以形成结果来进行排序。作为一项优化,它还缓存了区域设置的日期名称,因此如果再次使用相同的当前区域设置(可能的情况)调用它,它不需要重新创建这个私有列表。

        import datetime
        import locale
        
        def weekdays(weekday):
            current_locale = locale.getlocale()
            if current_locale not in weekdays._days_cache:
                # Add day names from a reference date, Monday 2001-Jan-1 to cache.
                weekdays._days_cache[current_locale] = [
                    datetime.date(2001, 1, i).strftime('%A') for i in range(1, 8)]
            days = weekdays._days_cache[current_locale]
            index = days.index(weekday)
            return days[index:] + days[:index]
        
        weekdays._days_cache = {}  # initialize cache
        
        print(weekdays('Wednesday'))
        # ['Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday', 'Monday', 'Tuesday']
        

        除了不需要在函数中硬编码日期名称之外,使用datetime 模块的另一个优点是使用它的代码将自动在其他语言中工作。这可以通过更改语言环境然后使用相应语言的日期名称调用函数来说明。

        例如,虽然法国不是我的默认语言环境,但我可以将其设置为当前语言环境以进行测试,如下所示。注意:根据这篇Capitalization of day names 文章,星期几的名称在法语中不像在我的默认英语语言环境中那样大写,但这也会自动考虑在内,这意味着weekday 名称已通过它必须是当前语言环境的语言,并且区分大小写。当然,如果需要,您可以修改函数以忽略输入参数的字母大小写。

        # set or change locale
        locale.setlocale(locale.LC_ALL, 'french_france')
        
        print(weekdays('mercredi'))  # use French equivalent of 'Wednesday'
        # ['mercredi', 'jeudi', 'vendredi', 'samedi', 'dimanche', 'lundi', 'mardi']
        

        【讨论】:

        • 感谢这段代码,你的日子如何:days = [datetime.date(2001, 1, i).strftime('%A') for i in range(1,8)]
        • 这行代码通过调用datetime.date.strftime('%A') 七次从已知为星期一的日期开始生成一周中所有工作日的名称列表。这样做意味着没有必要将工作日名称硬编码到代码中,因此它变得独立于语言环境,因为被调用的函数是。
        【解决方案4】:

        您无需对工作日数组进行硬编码。它已经在calendar module 中可用。

        import calendar as cal
        
        def weekdays(weekday):
            start = [d for d in cal.day_name].index(weekday)
            return [cal.day_name[(i+start) % 7] for i in range(7)]
        

        【讨论】:

          【解决方案5】:

          嗯,您目前只搜索给定的工作日并设置为结果 :) 您可以使用 python 列表中的切片功能来执行此操作:

          result = days[days.index(weekday):] + days[:days.index(weekdays)]
          

          【讨论】:

          • 好主意——基本上只是循环旋转days 列表,以便请求的weekday 在结果中排​​在第一位。不过,最好只找到一次索引,这只需要两行。 (另外,有一个错字,最后的weekdays 应该是weekday)。
          【解决方案6】:

          使用标准库的另一种方法:

          days = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday',
                  'Sunday']
          def weekdays(weekday):
            n = days.index(weekday)
            return list(itertools.islice(itertools.cycle(days), n, n + 7))
          

          在这种情况下,Itertools 有点多。由于您知道最多需要一个额外的周期,因此您可以手动完成:

          days = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday',
                  'Sunday']
          days += days
          def weekdays(weekday):
            n = days.index(weekday)
            return days[n:n+7]
          

          两者都给出了预期的输出:

          >>> weekdays("Wednesday")
          ['Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday', 'Monday', 'Tuesday']
          >>> weekdays("Sunday")
          ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']
          >>> weekdays("Monday")
          ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']
          

          【讨论】:

            【解决方案7】:

            记住工作日周期是一种更快的方法。因此,我们只需要获取我们想要包含列表的第一天,并将剩余的 6 个元素添加到末尾。或者换句话说,我们从起始日开始获取工作日列表,附加另一个完整的一周,并仅返回前 7 个元素(对于整个星期)。

            days = ('Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday')
            def weekdays ( weekday ):
                index = days.index( weekday )
                return list( days[index:] + days )[:7]
            
            >>> weekdays( 'Wednesday' )
            ['Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday', 'Monday', 'Tuesday']
            

            【讨论】:

            • 应该是 i = days.index( weekday )
            • @ncray:呃,谢谢,没有注意到我的两个版本之间存在命名差异!
            【解决方案8】:
            def weekdays(day):
                days = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']
                i=days.index(day) # get the index of the selected day
                d1=days[i:] #get the list from an including this index
                d1.extend(days[:i]) # append the list form the beginning to this index
                return d1
            

            如果你想测试它是否有效:

            def test_weekdays():
                days = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']
                for day in days:
                    print weekdays(day)
            

            【讨论】:

            • 而:d1=days[i:] #get the list from an including this indexd1.extend(days[:i]) # append the list form the beginning to this index可能更容易理解,可以简化为:d1=days[i:]+days[:i]
            【解决方案9】:

            这里有更多你想要的:

            def weekdays(weekday):
                days = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']
                index = days.index(weekday)
                return (days + days)[index:index+7]
            

            【讨论】:

            • 正是,我的想法:)
            【解决方案10】:

            每次运行 for 循环时,day 变量都会发生变化。所以一天等于你的输入只有一次。使用“Sunday”作为输入,它首先检查Monday = Sunday,然后如果Tuesday = Sunday,然后如果Wedday = Sunday,直到最后发现Sunday = Sunday,然后返回Sunday。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2023-01-12
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多