我的任务是定义一个函数
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'
我做错了什么?
您的代码仅返回一天名称的原因是因为
weekday
永远不会匹配 days
元组中的多个字符串,因此不会添加其后面的任何一周中的日子(也不会环绕到之前的那些)。即使它以某种方式完成,它仍然会将它们作为一个长字符串返回,因为您将 result
初始化为空字符串,而不是空 list
。
这里有一个解决方案,它使用
datetime
模块创建当前区域设置语言中以“Monday”开头的所有工作日名称的列表。然后使用该列表以返回的所需顺序创建另一个名称列表。它通过在原始列表中查找指定日期的索引,然后将相对于该索引的两个片段拼接在一起以形成结果来进行排序。作为一项优化,它还缓存区域设置的日期名称,因此如果使用相同的当前区域设置再次调用它(可能的情况),则不需要重新创建此私有列表。
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
模块的另一个优点是使用它的代码将自动以其他语言运行。这可以通过更改区域设置然后使用相应语言的日期名称调用该函数来说明。
例如,虽然法国不是我的默认区域设置,但我可以将其设置为当前区域设置以进行测试,如下所示。注意:根据这篇日期名称的大写文章,星期几的名称在法语中并不像在我的默认英语语言环境中那样大写,但这也会自动考虑在内,这意味着
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']
一个更快的方法是记住工作日循环。因此,我们只需要获取想要包含在列表中的第一天,并将剩余的 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']
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
如果您想测试它是否有效:
def test_weekdays():
days = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']
for day in days:
print weekdays(day)
您不需要对工作日数组进行硬编码。它已经在日历模块中可用。
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)]
这里还有您想要的更多内容:
def weekdays(weekday):
days = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']
index = days.index(weekday)
return (days + days)[index:index+7]
嗯,您当前仅搜索给定的工作日并设置为结果:) 您可以使用 python list 中的切片功能来执行此操作:
result = days[days.index(weekday):] + days[:days.index(weekdays)]
您的
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']
每次运行 for 循环时,day 变量都会发生变化。所以一天只等于你的输入一次。使用“Sunday”作为输入,它首先检查星期一是否=星期日,然后检查星期二是否=星期日,然后检查星期三=星期日,直到最后发现星期日=星期日并返回星期日。
使用标准库的另一种方法:
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']
下面的代码将根据您想要的 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)]
您可以使用Python标准的
calendar
模块和非常方便的类似列表的deque
对象。这样,我们只需将日期列表旋转到我们想要的日期即可。
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')
输出:
deque(['Wednesday',
'Thursday',
'Friday',
'Saturday',
'Sunday',
'Monday',
'Tuesday'])
我的简单方法是:
result = days[days.index(weekday):] + days[:days.index(weekdays)]
我希望这对你有帮助。