Return a list of weekdays, starting with given weekday
Asked Answered
H

12

14

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:

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

So far I've come up with this one:

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

But this prints the input day only:

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

What am I doing wrong?

Hunsaker answered 2/11, 2010 at 22:44 Comment(0)
Q
7
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 and including this index
    d1.extend(days[:i]) # append the list from the beginning to this index
    return d1

If you want to test that it works:

def test_weekdays():
    days = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']
    for day in days:
        print weekdays(day)
Quadratics answered 2/11, 2010 at 23:22 Comment(1)
while: d1=days[i:] #get the list from an including this index and d1.extend(days[:i]) # append the list form the beginning to this index might be easier to understand, it can be simplified to: d1=days[i:]+days[:i]Clarethaclaretta
N
15

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']
Nata answered 3/11, 2010 at 1:9 Comment(2)
thaks for this piece of code, how you get days: days = [datetime.date(2001, 1, i).strftime('%A') for i in range(1,8)]Usury
That line of code generates a list of the names of all the weekdays of a week by calling datetime.date.strftime('%A') seven times starting from a date known to be a Monday. Doing it that way means it's unnecessary to hard-code weekday names into the code and therefore it becomes locale independent because the function being called is.Nata
N
11

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']
Nichollenicholls answered 2/11, 2010 at 23:3 Comment(2)
Should be i = days.index( weekday )Neil
@ncray: Ugh, thanks, didn't notice that there was a naming difference between my two versions!Nichollenicholls
Q
7
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 and including this index
    d1.extend(days[:i]) # append the list from the beginning to this index
    return d1

If you want to test that it works:

def test_weekdays():
    days = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']
    for day in days:
        print weekdays(day)
Quadratics answered 2/11, 2010 at 23:22 Comment(1)
while: d1=days[i:] #get the list from an including this index and d1.extend(days[:i]) # append the list form the beginning to this index might be easier to understand, it can be simplified to: d1=days[i:]+days[:i]Clarethaclaretta
G
7

You don't need to hardcode array of weekdays. It's already available in 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)]
Glasswork answered 9/7, 2014 at 5:3 Comment(0)
B
4

Hmm, you are currently only searching for the given weekday and set as result :) You can use the slice ability in python list to do this:

result = days[days.index(weekday):] + days[:days.index(weekdays)]
Begat answered 2/11, 2010 at 22:56 Comment(1)
Good idea -- basically just circularly rotate the days list so that the requested weekday is first in the result. Would be better to just find the index once, though, only that would take two lines. (Also, there's a typo, the weekdays at the end should just be weekday).Nata
C
4

Here's more what you want:

def weekdays(weekday):
    days = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']
    index = days.index(weekday)
    return (days + days)[index:index+7]
Cagliostro answered 2/11, 2010 at 22:57 Comment(1)
exactly, what i thought of :)Sorci
L
2

Your result variable is a string and not a list object. Also, it only gets updated one time which is when it is equal to the passed weekday argument.

Here's an implementation:

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

Example output:

>>> 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']
Lavern answered 2/11, 2010 at 23:33 Comment(0)
D
1

Every time you run the for loop, the day variable changes. So day is equal to your input only once. Using "Sunday" as input, it first checked if Monday = Sunday, then if Tuesday = Sunday, then if Wednesday = Sunday, until it finally found that Sunday = Sunday and returned Sunday.

Delaine answered 2/11, 2010 at 22:49 Comment(0)
Y
1

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']
Yen answered 8/11, 2010 at 5:29 Comment(0)
M
0

The code below will gnereate a list based on X days you want a head , of you want to generate list of days going back change the [ minus to plus ]

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)]
Mcdougall answered 30/5, 2021 at 18:21 Comment(0)
B
0

You can use Python standard calendar module with very convenient list-like deque object. This way, we just have to rotate the list of the days to the one we want.

import calendar
from collections import deque

def get_weekdays(first: str = 'Monday') -> deque[str]:
    weekdays = deque(calendar.day_name)
    weekdays.rotate(-weekdays.index(first))
    return weekdays

get_weekdays('Wednesday')

that outputs:

deque(['Wednesday',
       'Thursday',
       'Friday',
       'Saturday',
       'Sunday',
       'Monday',
       'Tuesday'])
Bromine answered 3/12, 2022 at 13:29 Comment(0)
O
0

My simple approach would be:

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

I hope this is helpful.

Optimistic answered 3/12, 2022 at 14:47 Comment(1)
You provided exactly the same answer as this one: https://mcmap.net/q/791135/-return-a-list-of-weekdays-starting-with-given-weekday. Could you improve your answer so it should not be flagged as plagiarism ?Bromine

© 2022 - 2025 — McMap. All rights reserved.