J'ai une liste de vacances en tuples:

holidays = [('Easter', ('Apr', 1), 0),
            ('Earth Day', ('Apr', 22), 0),
            ('Pearl Harbor Rememberance Day', ('Dec', 7), 0),
            ('Christmas Day', ('Dec', 25), 50),
            ('Groundhog Day', ('Feb', 2), 0)]

Et une fonction pour les trier:

def holiday1(holidays : [(str,(str,int),int)]) -> [(str,(str,int),int)]:
    return sorted(holidays, key=lambda x:x[1])

Je les ai triés par mois par ordre alphabétique mais je veux les trier par position de mois. (par exemple, Jan = 1, Feb = 2, etc.)

J'ai créé un dictionnaire pour les mois:

months = {'Jan': 1, 'Feb': 2, 'Mar': 3, 'Apr': 4, 'May': 5, 'Jun': 6, 'Jul': 7, 'Aug': 8, 'Sep': 9, 'Oct': 10, 'Nov': 11, 'Dec': 12}

Je ne sais pas comment utiliser le dict «mois» pour trier la liste des tuples afin que le résultat soit:

holidays = [('Groundhog Day', ('Feb', 2), 0),
            ('Easter', ('Apr', 1), 0),
            ('Earth Day', ('Apr', 22), 0),
            ('Pearl Harbor Rememberance Day', ('Dec', 7), 0),
            ('Christmas Day', ('Dec', 25), 50)]
2
Jonathan C 11 avril 2018 à 22:35

3 réponses

Meilleure réponse

Les éléments que nous trions sont des 3-tuples où le deuxième élément est à nouveau un tuple. Nous sommes intéressés par le mois, qui est le premier élément du deuxième élément du tuple, donc nous pouvons y accéder avec x[1][0]. Mais bien sûr, nous ne voulons pas trier cela par ordre alphabétique, mais dans l'ordre des mois, nous pouvons donc effectuer une recherche avec months[x[1][0]]. Nous pouvons donc le trier uniquement en tenant compte du mois avec:

# only taking month into account
return sorted(holidays, key=lambda x: months[x[1][0]])

Mais je suppose qu'en cas de égalité , vous voulez tenir compte de la journée. La bonne chose à propos des tuples est que si vous les comparez, Python contiendra d'abord les premiers éléments des deux tuples. En cas d'égalité, il comparera le deuxième élément des deux tuples, etc.

# taking month and day into account
return sorted(holidays, key=lambda x: (months[x[1][0]], x[1][1]))

MODIFIER : dans le cas où vous souhaitez trier les vacances par nom si le mois et le jour sont égaux, nous pouvons construire 3 tuples:

# taking month, day and name into account
return sorted(holidays, key=lambda x: (months[x[1][0]], x[1][1], x[0]))
5
Willem Van Onsem 11 avril 2018 à 19:49

Utilisez une fonction clé qui classe l'objet que vous souhaitez trier.

def by_month(holiday):
    """sort by month, then day, then name of holiday"""
    holiday_name = holiday[0]
    month, day = holiday[1]
    month_value = months[month]
    return month_value, day, holiday_name

sorted(holidays, key=by_month)

La sortie serait

[('Groundhog Day', ('Feb', 2), 0),
 ('Easter', ('Apr', 1), 0),
 ('Earth Day', ('Apr', 22), 0),
 ('Pearl Harbor Rememberance Day', ('Dec', 7), 0),
 ('Christmas Day', ('Dec', 25), 50)]
2
sytech 11 avril 2018 à 19:46

Au lieu d'utiliser des structures de données et des valeurs ad hoc pour représenter un jour férié, définissez des types dont les valeurs se comportent correctement.

Tout d'abord, créez un type dédié pendant des mois, au lieu d'utiliser simplement des chaînes régulières.

from enum import IntEnum, auto, unique, EnumMeta

Month = IntEnum('Month',
        "Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec".split())

Ensuite, définissez une classe pour représenter un jour férié, au lieu d'utiliser des tuples simples.

from functools import total_ordering

@total_ordering
class Holiday:
    def __init__(self, name, month, day, x):
        self.name = name
        self.month = month
        self.day = day
        self.x = x
        self.sort_key = (self.month, self.day, self.name)

    def __lt__(self, other):
        return self.sort_key < other.sort_key

    def __eq__(self, other):
        return self.sort_key == other.sort_key and self.x == other.x

    def __str__(self):
        return "{} ({} {})".format(self.name, self.month._name_, self.day)

Vos vacances sont désormais triables sans effort supplémentaire:

holidays = [
    Holiday('Easter', Month.Apr, 1, 0),
    Holiday('Earth Day', Month.Apr, 22, 0),
    Holiday('Pearl Harbor Rememberance Day', Month.Dec, 7, 0),
    Holiday('Christmas Day', Month.Dec, 25, 50),
    Holiday('Groundhog Day', Month.Feb, 2, 0)
    ]

for h in sorted(holidays):
    print(h)

Les sorties

Groundhog Day (Feb 2)
Easter (Apr 1)
Earth Day (Apr 22)
Pearl Harbor Rememberance Day (Dec 7)
Christmas Day (Dec 25)
0
chepner 11 avril 2018 à 20:19