【问题标题】:Is there an obvious way to sort this list of data by time in Python有没有一种明显的方法可以在 Python 中按时间对这个数据列表进行排序
【发布时间】:2019-11-11 16:07:48
【问题描述】:

以下是我在列表中的数据。 'm' 是分钟,'h' 是小时,我需要用 Python 从最短到最长排序。

10m
10m
10m
11h59m
11m
12m
13h24m
13m
13m
13m
14m
14m
15m
17m
17m
1h01m
1h05m
1h05m
1h11m
1h15m
1h19m
1h25m
1h30m
1h31m
1h41m
1h46m
1h50m
1h54m
1m
20m
21m
22m
22m
22m
24m
25m
28m
28m
28m
29m
2h00m
2h07m
2h24m
2h27m
2h35m
2h51m
2h51m
2m
2m
2m
2m
2m
2m
2m
30m
31m
31m
31m
32m
32m
34m
35m
37m
3h18m
3h24m
3h28m
3h31m
3h43m
3h45m
3h53m
3m
3m
3m
40m
44m
4h11m
4h25m
4h43m
4h45m
4h57m
4m
4m
4m
4m
51m
51m
55m
58m
5h29m
5h39m
5h40m
6h06m
6h13m
6h20m
6m
7h16m
7h36m
7h43m
7m
8h50m
8m
8m
8m
8m
9h39m
9m
9m
9m
9m
9m
9m

【问题讨论】:

  • 是的,创建将字符串转换为数字然后按该数字排序的函数。
  • 您可能应该首先编写一个解析器,将总时间转换为可排序的类似整数的对象(可能是总分钟数),而不是执行字典排序。然后,您可以使用 Python 中的 sort 函数轻松完成此操作。也许使用一个字典,其键是字符串的输入,值是总时间(以分钟为单位)。
  • @CaitLANJenner:实际上,sorted 采用 key 可以处理的参数。不需要字典。

标签: python list sorting time


【解决方案1】:

您可以使用字典将符号映射到以分钟或秒为单位的持续时间,无论您的最小单位是什么,然后使用正则表达式提取持续时间的各个部分并得到它们的总和。

>>> import re
>>> d = {"s": 1, "m": 60, "h": 3600}
>>> def seconds(line):
...    return sum(int(n) * d[u] for n, u in re.findall("(\d+)(\w)", line))
...
>>> seconds("8h50m")
31800

然后将该函数用作keysorted

>>> sorted(lst, key=seconds)
['2m', '2m', '2m', ..., '7h43m', '8h50m', '9h39m']

【讨论】:

  • 您可以,当然,也可以使用“适当的”时间解析功能,例如strptime,但我发现很难使用那些with "optional bits"
【解决方案2】:

这是实现目标的另一种方法。

新版本:

def conversion(t):
    """ convert time to minutes """
    if 'h' in t:
        hours = int(t.split('h')[0])
        minutes = int(t.split('h')[1].split('m')[0])
        minutes = hours * 60 + minutes
    else:
        minutes = int(t.split('m')[0])

    return minutes

if __name__ == "__main__":
    values = ['10m', '10m', '10m', '11h59m', '11m', '12m', '13h24m', '13m', '13m', '13m', '14m', '14m', '15m', '17m', '17m', '1h01m', '1h05m', '1h05m', '1h11m', '1h15m', '1h19m', '1h25m', '1h30m', '1h31m', '1h41m', '1h46m', '1h50m', '1h54m', '1m', '20m', '21m', '22m', '22m', '22m', '24m', '25m', '28m', '28m', '28m', '29m', '2h00m', '2h07m', '2h24m', '2h27m', '2h35m', '2h51m', '2h51m', '2m', '2m', '2m', '2m', '2m', '2m', '2m', '30m', '31m', '31m', '31m', '32m', '32m', '34m', '35m', '37m', '3h18m', '3h24m', '3h28m', '3h31m', '3h43m', '3h45m', '3h53m', '3m', '3m', '3m', '40m', '44m', '4h11m', '4h25m', '4h43m', '4h45m', '4h57m', '4m', '4m', '4m', '4m', '51m', '51m', '55m', '58m', '5h29m', '5h39m', '5h40m', '6h06m', '6h13m', '6h20m', '6m', '7h16m', '7h36m', '7h43m', '7m', '8h50m', '8m', '8m', '8m', '8m', '9h39m', '9m', '9m', '9m', '9m', '9m', '9m']
    print(sorted(values, key=conversion))

输出:

['1m', '2m', '2m', '2m', '2m', '2m', '2m', '2m', '3m', '3m', '3m', '4m', '4m', '4m', '4m', '6m', '7m', '8m', '8m', '8m', '8m', '9m', '9m', '9m', '9m', '9m', '9m', '10m', '10m', '10m', '11m', '12m', '13m', '13m', '13m', '14m', '14m', '15m', '17m', '17m', '20m', '21m', '22m', '22m', '22m', '24m', '25m', '28m', '28m', '28m', '29m', '30m', '31m', '31m', '31m', '32m', '32m', '34m', '35m', '37m', '40m', '44m', '51m', '51m', '55m', '58m', '1h01m', '1h05m', '1h05m', '1h11m', '1h15m', '1h19m', '1h25m', '1h30m', '1h31m', '1h41m', '1h46m', '1h50m', '1h54m', '2h00m', '2h07m', '2h24m', '2h27m', '2h35m', '2h51m', '2h51m', '3h18m', '3h24m', '3h28m', '3h31m', '3h43m', '3h45m', '3h53m', '4h11m', '4h25m', '4h43m', '4h45m', '4h57m', '5h29m', '5h39m', '5h40m', '6h06m', '6h13m', '6h20m', '7h16m', '7h36m', '7h43m', '8h50m', '9h39m', '11h59m', '13h24m']

旧版代码

def conversion(t):
    """ convert time to minutes """
    if 'h' in t:
        hours = int(t.split('h')[0])
        minutes = int(t.split('h')[1].split('m')[0])
        minutes = hours * 60 + minutes
    else:
        minutes = int(t.split('m')[0])

    return minutes

def back_conversion(minutes):
    """ convert minutes to time """
    if minutes >= 60:
        hours = minutes // 60
        newminutes = minutes % 60
        if newminutes == 0:
            result = '{}h'.format(hours)
        else:
            result = '{}h{}m'.format(hours, newminutes)
    else:
        result = '{}m'.format(minutes)

    return result


if __name__ == "__main__":
    values = ['10m', '10m', '10m', '11h59m', '11m', '12m', '13h24m', '13m', '13m', '13m', '14m', '14m', '15m', '17m', '17m', '1h01m', '1h05m', '1h05m', '1h11m', '1h15m', '1h19m', '1h25m', '1h30m', '1h31m', '1h41m', '1h46m', '1h50m', '1h54m', '1m', '20m', '21m', '22m', '22m', '22m', '24m', '25m', '28m', '28m', '28m', '29m', '2h00m', '2h07m', '2h24m', '2h27m', '2h35m', '2h51m', '2h51m', '2m', '2m', '2m', '2m', '2m', '2m', '2m', '30m', '31m', '31m', '31m', '32m', '32m', '34m', '35m', '37m', '3h18m', '3h24m', '3h28m', '3h31m', '3h43m', '3h45m', '3h53m', '3m', '3m', '3m', '40m', '44m', '4h11m', '4h25m', '4h43m', '4h45m', '4h57m', '4m', '4m', '4m', '4m', '51m', '51m', '55m', '58m', '5h29m', '5h39m', '5h40m', '6h06m', '6h13m', '6h20m', '6m', '7h16m', '7h36m', '7h43m', '7m', '8h50m', '8m', '8m', '8m', '8m', '9h39m', '9m', '9m', '9m', '9m', '9m', '9m']
    sorted_values  = sorted([conversion(v) for v in values])
    final_results = [back_conversion(v) for v in sorted_values]
    print(final_results)

输出

['1m', '2m', '2m', '2m', '2m', '2m', '2m', '2m', '3m', '3m', '3m', '4m', '4m', '4m', '4m', '6m', '7m', '8m', '8m', '8m', '8m', '9m', '9m', '9m', '9m', '9m', '9m', '10m', '10m', '10m', '11m', '12m', '13m', '13m', '13m', '14m', '14m', '15m', '17m', '17m', '20m', '21m', '22m', '22m', '22m', '24m', '25m', '28m', '28m', '28m', '29m', '30m', '31m', '31m', '31m', '32m', '32m', '34m', '35m', '37m', '40m', '44m', '51m', '51m', '55m', '58m', '1h1m', '1h5m', '1h5m', '1h11m', '1h15m', '1h19m', '1h25m', '1h30m', '1h31m', '1h41m', '1h46m', '1h50m', '1h54m', '2h', '2h7m', '2h24m', '2h27m', '2h35m', '2h51m', '2h51m', '3h18m', '3h24m', '3h28m', '3h31m', '3h43m', '3h45m', '3h53m', '4h11m', '4h25m', '4h43m', '4h45m', '4h57m', '5h29m', '5h39m', '5h40m', '6h6m', '6h13m', '6h20m', '7h16m', '7h36m', '7h43m', '8h50m', '9h39m', '11h59m', '13h24m']

【讨论】:

  • 如果可以只使用sorted(values, key=conversion),为什么还要来回转换?
  • 你是对的。谢谢你指出。我会更新代码。
  • 非常感谢,另一个好主意。我将使用顶部评论来减少行数。
猜你喜欢
  • 2013-03-08
  • 1970-01-01
  • 2020-08-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-10-06
相关资源
最近更新 更多