【问题标题】:How to sort a list of times如何对时间列表进行排序
【发布时间】:2021-12-20 08:23:32
【问题描述】:

我刚开始使用 Python,想知道如何进行排序

从最早到最晚的列表。

('5:00PM','2:00PM','7:00AM','8:45PM','12:00PM')

感谢任何帮助。

【问题讨论】:

  • 你试过什么?展示你的作品。此外,这些不是时间列表,它们是字符串。
  • 你的分拣条件是什么?你展示的是一个元组而不是一个列表。您是否尝试过这样做?你能展示你的代码吗?
  • 编写一个函数,返回列表中时间的 24 小时等效整数,然后将其用作 list.sort() 的键函数

标签: python


【解决方案1】:

我建议您安装 PyPi DateTime 软件包,并将这些工具用于您想要的任何操作。手头的问题看起来像:

stamps = ('5:00PM','2:00PM','7:00AM','8:45PM','12:00PM')
DT_stamps = [DateTime(s) for s in stamps]
DT_stamps.sort()

实施细节留给学生练习。 :-)

【讨论】:

  • 这不会留下排序字符串列表的结果。
  • OP 声明它们是时间列表,而不是字符串,所以我选择了这个策略。如果真正的问题是对字符串进行排序,那么我们马上就会澄清这个效果。 :-)
【解决方案2】:

如果时间总是采用这种格式,您可以将时间分成小节。

x = "12:30PM"
# Use python's string slicing to split on the last two characters
time, day_half = x[:-2], x[-2:]
# Use python's string.split() function to get the difference between hours and minutes
# Because "11" < "2" for strings, we need to convert them to integers
hour, minute = [int(t) for t in time.split(":")]
# Get the remainder because 12 should actually be 0
hour = hour % 12
# Output it as a tuple, which sorts based on each element from left to right
sortable = (day_half, hour, minute)
#: ("PM", 12, 30)

总结一下,使用类似的东西:

def sortable_time(time_str):
    time, day_half = time_str[:-2], time_str[-2:]
    hour, minute = [int(t) for t in time.split(":")]
    hour = hour % 12
    return day_half, hour, minute

# When sorting, use `key` to define the method we're sorting with
# (The returned list however, will be filled with the original strings)
result = sorted(your_time_list, key=sortable_time)
#: ['7:00AM', '12:00PM', '2:00PM', '5:00PM', '8:45PM']

如果您不能保证最后两个字母或中间的冒号,您最好使用像 Prune 建议的库。

【讨论】:

  • 感谢您的回复!我相信我只能使用标准库。
  • 没问题@alex756 如果这些回复中的任何一个对您有所帮助,请不要忘记投票并将其中一个标记为正确,以便其他人可以找到答案。
【解决方案3】:

仅在标准库的python3中:

import time
hours = ('5:00PM','2:00PM','7:00AM','8:45PM','12:00PM')
format = '%I:%M%p'
time_hours = [time.strptime(t, format) for t in hours]
result = [time.strftime(format, h) for h in sorted(time_hours)]
assert result == ['07:00AM', '12:00PM', '02:00PM', '05:00PM', '08:45PM']

【讨论】:

    【解决方案4】:

    您显示的不是时间列表,而是字符串元组。元组是不可变的,不能排序,只有像列表这样的可变集合可以。所以首先你需要将你的元组转换为一个列表:

    times = ['5:00PM','2:00PM','7:00AM','8:45PM','12:00PM']
    

    您现在可以尝试对该列表进行排序,但字符串不会按照您期望的方式排序。相反,您需要创建一个自定义排序函数,将列表中的值临时转换为struct_time 对象并使用这些对象进行排序。

    import time
    
    time_format = '%I:%M%p' # match hours, minutes and AM/PM
    
    def compare_as_time(time_str1, time_str2):
        # parse time strings to time objects
        time1 = time.strptime(time_str1, time_format)
        time2 = time.strptime(time_str2, time_format)
    
        # return comparison, sort expects -1, 1 or 0 to determine order
        if time1 < time2:
            return -1
        elif time1 > time2:
            return 1
        else:
            return 0
    

    现在您可以调用sorted() 并传入您的列表和自定义比较函数,您将获得一个字符串列表,按这些字符串中的时间排序:

    sorted_times = sorted(times, compare_as_time)
    

    Python 3 的注意事项: 前面的示例假定 Python 2。如果您使用的是 Python 3,则需要将比较函数转换为 key function。这可以使用functools.cmp_to_key() 来完成,如下所示:

    form functools import cmp_to_key
    
    sorted_times = sorted(times, key=cmp_to_key(compare_as_time))
    

    【讨论】:

    • 即使在 Python2 中,您也可以只指定 key 函数。这会将您的功能简化为简单的:sorted(times, key=lambda x: time.strptime(x, time_format))。注意:我实际上不喜欢lambdas,但在cmets 中很难def 函数。
    • 我特意写了这么久,以说明使用自定义比较器进行排序的工作原理。 OP 正在尝试学习和应用这一点,因此一个班轮没有那么有用。
    • 如果您认为说明已删除的功能很有帮助(cmp 已从 Python3 中的排序中删除),请添加一个警告,即答案仅适用于 python2。 OP没有指定他的版本,所以至少你的答案很可能对他不起作用。 :-)
    • @MSeifert 我已经更新了答案以包含 Python 3 改编版。
    猜你喜欢
    • 2013-07-16
    • 1970-01-01
    • 1970-01-01
    • 2019-03-12
    • 1970-01-01
    • 1970-01-01
    • 2012-12-16
    相关资源
    最近更新 更多