Return a list of weekdays, starting with given weekday

后端 未结 9 2348
情书的邮戳
情书的邮戳 2021-02-07 23:53

My task is to define a function weekdays(weekday) that returns a list of weekdays, starting with the given weekday. It should work like this:

相关标签:
9条回答
  • 2021-02-08 00:35

    A far quicker approach would be to keep in mind, that the weekdays cycle. As such, we just need to get the first day we want to include the list, and add the remaining 6 elements to the end. Or in other words, we get the weekday list starting from the starting day, append another full week, and return only the first 7 elements (for the full week).

    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']
    
    0 讨论(0)
  • 2021-02-08 00:37

    Another approach using the standard library:

    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 is a bit much in this case. Since you know at most one extra cycle is needed, you could do that manually:

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

    Both give the expected output:

    >>> 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']
    
    0 讨论(0)
  • 2021-02-08 00:42

    The reason your code is only returning one day name is because weekday will never match more than one string in the days tuple and therefore won't add any of the days of the week that follow it (nor wrap around to those before it). Even if it did somehow, it would still return them all as one long string because you're initializing result to an empty string, not an empty list.

    Here's a solution that uses the datetime module to create a list of all the weekday names starting with "Monday" in the current locale's language. This list is then used to create another list of names in the desired order which is returned. It does the ordering by finding the index of designated day in the original list and then splicing together two slices of it relative to that index to form the result. As an optimization it also caches the locale's day names so if it's ever called again with the same current locale (a likely scenario), it won't need to recreate this private list.

    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']
    

    Besides not needing to hard-code days names in the function, another advantage to using the datetime module is that code utilizing it will automatically work in other languages. This can be illustrated by changing the locale and then calling the function with a day name in the corresponding language.

    For example, although France is not my default locale, I can set it to be the current one for testing purposes as shown below. Note: According to this Capitalization of day names article, the names of the days of the week are not capitalized in French like they are in my default English locale, but that is taken into account automatically, too, which means the weekday name passed to it must be in the language of the current locale and is also case-sensitive. Of course you could modify the function to ignore the lettercase of the input argument, if desired.

    # 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']
    
    0 讨论(0)
提交回复
热议问题