Возврат списка будних дней

Моя задача - определить функцию 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']