繁体   English   中英

按月python排序元组列表

[英]Sort list of tuples by month python

我有元组中的假期列表:

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

以及对它们进行排序的功能:

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

我按字母顺序按月分类,但我想按月份的位置对它们进行排序。 (例如Jan = 1,Feb = 2等)

我已经为这几个月创建了一本字典:

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}

我不确定如何使用dict'months'来排序元组列表,以便结果如下:

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

我们排序的元素是3元组,其中第二个元素也是元组。 我们感兴趣的是月份,它是元组第二个元素的第一个元素,所以我们可以用x[1][0]来访问它。 但是我们当然不希望按字母顺序排序,但是按月的顺序排序,所以我们可以用months[x[1][0]]执行查找。 因此,我们可以排序只服用一个月到帐户:

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

但我的猜测是,如果出现平局 ,你需要考虑这一天。 关于元组的好处是,如果你比较它们,Python将首先包含两个元组的第一个元素。 如果是平局,它将比较两个元组的第二个元素等。我们可以通过让key返回2元组来使用它:首先是月份的索引,然后是日期:

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

编辑 :如果您希望按月份和日期相同的方式按名称对假期进行排序,我们可以构建3元组:

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

使用键功能对要排序的对象进行排名。

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)

输出将是

[('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)]

不要使用ad-hoc数据结构和值来表示假日,而是定义其值正确行为的类型。

首先,创建几个月的专用类型,而不是仅使用常规字符串。

from enum import IntEnum, auto, unique, EnumMeta

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

接下来,定义一个表示假日的类,而不是使用普通元组。

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)

现在您的假期可以排序而无需任何进一步的努力:

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)

输出

Groundhog Day (Feb 2)
Easter (Apr 1)
Earth Day (Apr 22)
Pearl Harbor Rememberance Day (Dec 7)
Christmas Day (Dec 25)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM