2010-11-02 8 views
10

Mi tarea es definir una función weekdays(weekday) que devuelve una lista de días de la semana, comenzando con el día de la semana. Se debe trabajar de esta manera:Devolver una lista de días de la semana

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

Hasta ahora se me ha ocurrido con éste:

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

Pero esto imprime sólo el día de entrada:

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

¿Qué estoy haciendo ¿incorrecto?

Respuesta

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 

Y si desea probar que funciona:

def test_weekdays(): 
    days = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'] 
    for day in days: 
     print weekdays(day) 
+0

buena y simple solución) – Gusto

1

Cada vez que ejecuta el ciclo for, la variable del día cambia. Entonces el día es igual a tu entrada solo una vez. Usando "Sunday" como entrada, primero verificó si Monday = Sunday, luego si Tuesday = Sunday, luego si Wednesday = Sunday, hasta que finalmente encontró ese domingo = domingo y regresó el domingo.

4

Hmm, que está en la actualidad sólo buscando el día de la semana dado y establecido como resultado :) Puede utilizar la capacidad rebanada en la lista de Python para hacer esto:

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

Buena idea - básicamente circular girar el 'days' lista para que la solicitada 'día laborable' es el primero en el resultado. Sería mejor solo encontrar el índice una vez, solo que tomaría dos líneas. (Además, hay un error tipográfico, los 'días de la semana' al final solo deberían ser' día de la semana'). – martineau

4

Aquí hay más de lo que quieren:

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

exactamente, lo que pensé :) – st0le

10

Un enfoque mucho más rápido sería tener en cuenta que los días de la semana ciclo. Como tal, solo necesitamos obtener el primer día que queremos incluir la lista y agregar los 6 elementos restantes hasta el final. O en otras palabras, obtenemos la lista de días laborables a partir del día de inicio, agregamos otra semana completa y devolvemos solo los primeros 7 elementos (para la semana completa).

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

Debería ser i = days.index (día de la semana) – ncray

+0

@ncray: ¡Uf, gracias, no noté que había una diferencia de nombres entre mis dos versiones! – poke

0

La variable de result es una cadena y no un objeto de lista. Además, como han mencionado otros, solo se actualiza una vez, que es cuando es igual al argumento pasado weekday.

Otra aplicación:

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

La razón de su código sólo se está volviendo un nombre se debe a que el día weekday nunca coincidirán con más de una cuerda en el days tupla y por lo tanto no va a añadir cualquiera de los días de la semana que lo sigue (ni se envuelve a los que están antes). Incluso si lo hiciera de alguna manera, todavía los devolvería todos como una cadena larga porque está inicializando result en una cadena vacía, no en un list vacío.

Aquí hay una solución que usa el módulo datetime para crear una lista de todos los nombres de los días de la semana que comienzan con "Lunes" en el idioma de la configuración regional actual. Esta lista se usa para crear otra lista de nombres en el orden deseado que se devuelve. Realiza el pedido buscando el índice del día designado en la lista original y luego empalmando dos sectores de este en relación con ese índice para formar el resultado. Como optimización, también almacena en caché los nombres de día de la configuración regional, por lo que si alguna vez se llama nuevamente con la misma configuración regional actual (un escenario probable), no será necesario volver a crear esta lista privada.

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

Además de no necesitar de código duro día de nombres en la función, otra de las ventajas de utilizar el módulo de datetime es que la utilización de código que va a funcionar automáticamente en otras lenguas. Esto se puede ilustrar cambiando la configuración regional y luego llamando a la función con un nombre de día en el idioma correspondiente.

Por ejemplo, aunque Francia no es mi configuración regional predeterminada, puedo configurarla para que sea la actual, como se muestra a continuación. Nota: Según este artículo Capitalization of day names, los nombres de los días de la semana no están en mayúscula en francés como en mi configuración predeterminada en inglés, pero eso también se tiene en cuenta automáticamente, lo que significa que el nombre weekday que se le transfirió debe escribirse en el idioma de la configuración regional actual y también distingue entre mayúsculas y minúsculas. Por supuesto, puede modificar la función para ignorar el lettercase del argumento de entrada, si lo desea.

# 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 para este fragmento de código, cómo obtienes días: *** 'days = [datetime.date (2001, 1, i) .strftime ('% A') para i en rango (1 , 8)] '*** – andi

+1

Esa línea de código genera una lista de los nombres de todos los días de la semana llamando' datetime.date.strftime ('% A') 'siete veces a partir de una fecha que se sabe que es un lunes. Hacerlo de esa manera significa que no es necesario codificar los nombres de los días de la semana en el código y, por lo tanto, se convierte en independiente de la configuración regional porque la función que se llama es. – martineau

0

Otro enfoque usando la biblioteca estándar:

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 es un poco mucho en este caso. Puesto que usted sabe, como máximo, se necesita un ciclo adicional, se puede hacer eso de forma manual:

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

Ambos dan el resultado esperado:

>>> 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

No es necesario para codificar gama de lunes a viernes. Ya está disponible en 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

Nadie ha establecido de manera concisa lo que (creo) es la solución más rápida:

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

menos llamadas, utilizando sólo .index() una vez, y cortar de manera eficiente hace de esta casi dos veces tan rápido como Poke's answer.

Otra alternativa podría ser el uso de collections.deque, que es más lento que el primer enfoque, pero ordenada en su capacidad para rotate():

from collections import deque 
def weekdays(weekday): 
    x = deque(days) 
    x.rotate(-days.index(weekday)) 
    return list(x) 
Cuestiones relacionadas