文字列のリストから最高の継続時間を取得する


8

以下のような期間のリストがあります

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

ここでd、日をh表し、時間をm表し、分を表します。

このリスト(14dこの場合)から最長の期間を取得したい。この文字列のリストからどうすれば取得できますか?


1
stackoverflow.com/a/4628148/1224467この回答には、文字列をタイムデルタに変換するソリューションがあります。これらはソートできます。
H4kor

回答:


12

純粋なpythonソリューション。私たちは、時間延長(間のマッピングを格納することができmhd)と分(ここではtime_map最高の時間を見つけるために、)。ここでは、マッピングを適用するためにmax()with 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

14

np.argmaxpd.to_timedelta

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文字列を期間(source)に変換しnp.argmax、最も高い要素のインデックスを返します。


プロジェクトでnumpyやpandasを使用するつもりはありませんが、この問題が発生していますが、これは、ライブラリー関数を効率的に使用して作業を完了する驚くべき例であることを言わなければなりません。
Rafiul Sabbir

4

ここでは悪いが、巧妙な方法で問題を解決し、絶対ハックです:Pythonのminmax機能は一緒に使用することができkey、それは要素、その関数を最小化または最大化を返すように、要素を比較するために使用される機能。key関数がタプルを返す場合、順序は、2番目のコンポーネントをタイブレーカーとして使用して、タプルの最初のコンポーネントによって決定されます。

我々はその最後の文字が事実を利用することができます'd''h'そして'm'アルファベット順に比較することができます。Dの AYは、より長い時間、私たちはより長いメートルの inute。つまり、最長の期間はアルファベット順に最小の文字を持ち、最大の整数をタイブレーカーとして使用します。その整数を最大化することは、その否定を最小化することと同じです。

>>> durations = ['5d', '20h', '1h', '7m', '14d', '1m']
>>> min(durations, key=lambda d: (d[-1], -int(d[:-1])))
'14d'

秒はs、週はW、月はMで表すことができますが、それでも機能します。ただし、年yまたは年のどちらかを含めると、ハックが破られますY。また10000000m、より大きな単位を代わりに使用できるような期間がないことにも依存しています。文字列は、常に可能な限り最大の単位を使用するAPIの出力であると想定しています。
kaya3

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

出力:

'14d'

この特定の文字列セットに役立ちますが、形式が異なる場合は、それに応じてタプルの最初の要素を調整する必要があります。ので、今のところ、それは理にかなっていますs> m> h> d


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

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

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"
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.