2010-11-02 5 views
10

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

Что я делаю неправильно?

ответ

3
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) 
+0

хорошее и простое решение) – Gusto

1

Каждый раз, когда вы запускаете цикл for, меняется переменная дня. Таким образом, день равен вашему вводу только один раз. Используя «воскресенье» в качестве входных данных, он сначала проверял, если понедельник = воскресенье, затем, если вторник = воскресенье, тогда, если среда = воскресенье, пока он наконец не найдет это воскресенье = воскресенье и вернется в воскресенье.

4

Хм, вы в настоящее время только поиск для данного дня недели и установить в качестве результата :) Вы можете использовать способность ломтика в списке питона сделать это:

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

Хорошая идея - в основном только циркулярно вращать 'days' список так, чтобы запрашиваемое 'weekday' является первым в результате. Было бы лучше просто найти индекс один раз, однако, только это займет две строки. (Кроме того, есть опечатка, 'weekdays' в конце должен быть просто' weekday'). – martineau

4

Вот еще, что вы хотите:

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

точно, о чем я думал :) – st0le

10

Более быстрый подход состоял бы в том, чтобы иметь в виду, что в будние дни цикл. Таким образом, нам просто нужно получить первый день, когда мы хотим включить этот список, и добавить оставшиеся 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'] 
+0

Должно быть i = days.index (рабочий день) – ncray

+0

@ncray: Ух, спасибо, не заметил, что между моими версиями была разница в именах! – poke

0

Ваш 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 
14

Причина ваш код возвращает только одно название дня, потому что 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 модуля является то, что код использования он будет автоматически работать и на других языках. Это можно проиллюстрировать, изменив локаль, а затем вызывая функцию с именем дня на соответствующем языке.

Например, хотя Франция не является моей базой по умолчанию, я могу установить ее как текущую для целей тестирования, как показано ниже. Примечание. В соответствии с этой статьей Capitalization of day names имена дней недели не капитализируются на французском языке, как в моем стандартном английском языке, но это также учитывается автоматически, что означает, что имя, переданное на него, должно быть 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'] 
+0

thaks для этой части кода, как вы получаете дни: *** 'days = [datetime.date (2001, 1, i) .strftime ('% A') для i в диапазоне (1 , 8)] '*** – andi

+1

Эта строка кода генерирует список имен всех будних дней недели, вызывая' datetime.date.strftime ('% A') 'семь раз, начиная с даты, известной как понедельник. Выполнение этого способа означает, что нет необходимости жестко указывать имена дней недели в коде, и поэтому он становится независимым от языка, потому что вызываемая функция. – martineau

0

Другой подход с использованием стандартной библиотеки:

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

Вам не нужно жёстко массив будням. Он уже доступен в 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)] 
1

Никто не сжато изложил то, что (я думаю) является самым быстрым решением:

def weekdays(weekday): 
    x = days.index(weekday) 
    return days[x:] + days[:x] 

Меньше звонков, используя только .index() один раз, и эффективно нарезка делает это почти в два раза быстрее Poke's answer.

Другой альтернативой может быть с помощью collections.deque, которая работает медленнее, чем первый подход, но в чистом виде в его способности rotate():

from collections import deque 
def weekdays(weekday): 
    x = deque(days) 
    x.rotate(-days.index(weekday)) 
    return list(x) 
Смежные вопросы