Возврат списка будних дней
Моя задача - определить функцию 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'
Что я делаю неправильно?
Ответы
Ответ 1
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)
Ответ 2
Причина, по которой ваш код возвращает только одно имя, заключается в том, что 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
заключается в том, что его использование будет автоматически работать на других языках. Это можно проиллюстрировать, изменив локаль и затем вызывая функцию с именем дня на соответствующем языке.
Например, хотя Франция не является моей базой по умолчанию, я могу установить ее как текущую для целей тестирования, как показано ниже. Примечание. В соответствии с этой Капитализация дней имен" названия дней недели не заглатываются на французском языке, как в моем английском языке по умолчанию locale, но это также учитывается автоматически, что означает, что переданное ему имя 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']
Ответ 3
Более быстрый подход состоял бы в том, чтобы иметь в виду, что в будние дни цикл. Таким образом, нам просто нужно получить первый день, когда мы хотим включить этот список, и добавить оставшиеся 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']
Ответ 4
Хм, вы в настоящее время ищете только этот будний день и задаете результат:)
Вы можете использовать возможность среза в списке python для этого:
result = days[days.index(weekday):] + days[:days.index(weekdays)]
Ответ 5
Здесь больше чего вы хотите:
def weekdays(weekday):
days = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']
index = days.index(weekday)
return (days + days)[index:index+7]
Ответ 6
Вам не нужно жестко задавать массив дней недели. Он уже доступен в календарном модуле.
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)]
Ответ 7
Каждый раз, когда вы запускаете цикл for, меняется переменная дня. Таким образом, день равен вашему вводу только один раз. Используя "воскресенье" в качестве входных данных, он сначала проверял, если понедельник = воскресенье, затем, если вторник = воскресенье, затем, если среда = воскресенье, пока он наконец не обнаружил, что воскресенье = воскресенье и вернулся в воскресенье.
Ответ 8
Никто не кратко изложил, что (я думаю) является самым быстрым решением:
def weekdays(weekday):
x = days.index(weekday)
return days[x:] + days[:x]
Меньше вызовов, только один раз используя .index()
, и эффективная нарезка делает это почти в два раза быстрее, чем Poke answer.
Другой альтернативой может быть использование collections.deque
, которое медленнее первого подхода, но опрятное в его способности rotate()
:
from collections import deque
def weekdays(weekday):
x = deque(days)
x.rotate(-days.index(weekday))
return list(x)
Ответ 9
Ваша переменная result
- это строка, а не объект списка. Кроме того, как отмечали другие, он обновляется только один раз, когда он равен переданному аргументу 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
Ответ 10
Другой подход, использующий стандартную библиотеку:
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']