从字符串列表中获取最长的持续时间

9
我有一个类似下面的持续时间列表。
['5d', '20h', '1h', '7m', '14d', '1m']

d代表天数,h代表小时数,m代表分钟数。

我想从这个列表中获取最长的持续时间(在这种情况下为14d)。如何从这个字符串列表中获取呢?


1
这个回答提供了一种将字符串转换为时间差的解决方案。这些时间差可以进行排序。 - H4kor
7个回答

15

pd.to_timedeltanp.argmax:

import numpy as np
import pandas as pd

durations = ['5d', '20h', '1h', '7m', '14d', '1m']

durations[np.argmax(pd.to_timedelta(durations))]
Out[24]: '14d'

pd.to_timedelta 将字符串转换为时间间隔 (来源),而 np.argmax 返回最高元素的索引。


虽然我在这个项目中不打算使用numpy和/或pandas,但我必须说这是一个使用库函数有效地完成工作的惊人例子。 - Rafiul Sabbir

13

纯Python解决方案。我们可以存储时间扩展名(m, h, d)与分钟之间的映射关系(在这里使用time_map),以查找最高持续时间。我们在这里使用max()key参数来应用我们的映射。

inp = ['5d', '20h', '1h', '7m', '14d', '1m']
time_map = {'m': 1, 'h': 60, 'd': 24*60}

print(max(inp, key=lambda x:int(x[:-1])*time_map[x[-1]]))  # -> 14d

5
这里有一个绝对的技巧,用一个不太好但很聪明的方法解决了问题:Python的min和max函数可以使用一个key函数来比较元素,使其返回最小或最大的元素。如果key函数返回一个元组,则使用元组的第一个组件确定顺序,使用第二个组件作为tie-breaker(分别代表排序优先级和次要优先级)。
我们可以利用最后的字符'd'、'h'和'm'可以按字母顺序比较这一事实;一天比一小时长,一小时比一分钟长。这意味着最长的持续时间在字母顺序中具有最小的字符,以最大的整数作为tie-breaker。最大化该整数等同于最小化它的负数。
>>> durations = ['5d', '20h', '1h', '7m', '14d', '1m']
>>> min(durations, key=lambda d: (d[-1], -int(d[:-1])))
'14d'

1
你可以将秒表示为s,周表示为W,月份表示为M,它仍然可以工作;但如果你包括年份,使用yY,这种方法就会失效。此外,它还依赖于没有任何持续时间,例如10000000m,其中可以使用更大的单位;我假设这些字符串是某个API的输出,该API始终使用最大的单位。 - kaya3

3

以下是一个使用正则表达式的解决方案:

import numpy as np
import re

new_list = []
x=['5d', '20h', '1h', '7m', '14d', '1m']
map_time={"d":1440, "h":60, "m":1}

for item in x:
    letter=re.findall("[a-zA-Z]+",item)
    number=re.findall("[1-9]+",item)
    new_list.append(map_time[letter[0]]*int(number[0]))

x[np.argmax(new_list)]

3
lst = ['5d', '20h', '1h', '7m', '14d', '1m']
max(lst, key=lambda s: (-ord(s[-1]), int(s[:-1])))

输出:

'14d'

这对于特定的一组字符串很有用,但如果格式不同,则需要相应调整元组的第一个元素。现在这仅仅是因为s > m > h > d才有意义。


2

只要您的时间格式正确,就可以使用单个正则表达式找到max

>>> import re
>>>
>>> durations = ['5d', '20h', '1h', '7m', '14d', '1m']
>>> pattern = re.compile(r'(?:(\d*)d)?(?:(\d*)h)?(?:(\d*)m)?')
>>> max(inp, key=lambda tme: tuple(map(int, pattern.match(tme).groups(default=0))))
'14d'

正则表达式创建了一个由天、小时和分钟组成的字符串元组。 tuple(map(int, ...)) 将其转换为整数。 max 选择这些元组中最大的,自然地将天数权重大于小时数,小时数权重大于分钟数。

1
一种可能的方式:

duration = ['5d', '20h', '1h', '7m', '14d', '1m', '2d']
duration_std = [0]*len(duration)

equivalence = {"d":60*60*24, "h":60*60, "m":60}

for idx, val in enumerate(duration):
    duration_std[idx] = int(val[:-1])*equivalence[val[-1]]

print(duration[duration_std.index(max(duration_std))])

输出
"14d"

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接