Holen Sie sich die höchste Dauer aus einer Liste von Zeichenfolgen

8

Ich habe eine Liste von Dauern wie unten

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

wo dsteht für Tage, hsteht für Stunden und msteht für Minuten.

Ich möchte die höchste Dauer aus dieser Liste erhalten ( 14din diesem Fall). Wie kann ich das aus dieser Liste von Zeichenfolgen erhalten?

Rafiul Sabbir
quelle
1
stackoverflow.com/a/4628148/1224467 Diese Antwort bietet eine Lösung, um Ihre Zeichenfolgen in Zeitleisten umzuwandeln. Diese können sortiert werden.
H4kor

Antworten:

12

Reine Python-Lösung. Wir konnten speichern Mapping zwischen unseren Zeiterweiterungen ( m, h, d) und Minuten (hier time_map), längere Haltbarkeit zu finden. Hier verwenden wir max()mit keyArgument, um unser Mapping anzuwenden.

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
Filip Młynarski
quelle
14

np.argmaxam pd.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_timedeltawandelt eine Zeichenfolge in eine Dauer ( Quelle ) um und np.argmaxgibt den Index des höchsten Elements zurück.

Nicolas Gervais
quelle
Obwohl ich für das Projekt kein Numpy und / oder Pandas verwenden werde, habe ich dieses Problem, aber ich muss sagen, dass dies ein erstaunliches Beispiel für die effiziente Verwendung von Bibliotheksfunktionen ist, um Ihre Arbeit zu erledigen.
Rafiul Sabbir
4

Hier ist ein absoluter Hack, der das Problem auf eine schlechte, aber clevere Weise löst: Pythons minund maxFunktionen können mit einer keyFunktion verwendet werden, die zum Vergleichen von Elementen verwendet wird, sodass das Element zurückgegeben wird, das diese Funktion minimiert oder maximiert. Wenn die keyFunktion ein Tupel zurückgibt, wird die Reihenfolge durch die erste Komponente des Tupels bestimmt, wobei die zweite Komponente als Verbindungsunterbrecher verwendet wird.

Wir können die Tatsache , dass die letzten Zeichen ausnutzen 'd', 'h'und 'm'können in alphabetischer Reihenfolge verglichen werden; a d ay ist länger als eine Stunde unseres länger als eine ist m inute. Dies bedeutet, dass die längste Dauer das minimale Zeichen in alphabetischer Reihenfolge hat, wobei die maximale Ganzzahl als Gleichstand dient. Das Maximieren dieser Ganzzahl entspricht dem Minimieren der Negation:

>>> durations = ['5d', '20h', '1h', '7m', '14d', '1m']
>>> min(durations, key=lambda d: (d[-1], -int(d[:-1])))
'14d'
kaya3
quelle
Sie könnten Sekunden als sund Wochen als Wund Monate als dargestellt haben M, und es würde immer noch funktionieren; Der Hack bricht ab, wenn Sie Jahre entweder yoder Yangeben. Es hängt auch davon ab, dass es keine Zeiträume gibt, in 10000000mdenen stattdessen eine größere Einheit verwendet werden könnte. Ich gehe davon aus, dass die Zeichenfolgen die Ausgabe einer API sind, die immer die größtmögliche Einheit verwendet.
Kaya3
3
lst = ['5d', '20h', '1h', '7m', '14d', '1m']
max(lst, key=lambda s: (-ord(s[-1]), int(s[:-1])))

Ausgabe:

'14d'

Nützlich für diesen bestimmten Satz von Zeichenfolgen, aber wenn sich das Format unterscheidet, muss das erste Element des Tupels entsprechend angepasst werden. Gerade jetzt macht es Sinn , weil s> m> h> d.

Turm
quelle
3

Hier ist eine Lösung mit regulären Ausdrücken

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)]
Kingindanord
quelle
2

Vorausgesetzt, Ihre Zeiten sind gut geformt, können Sie die maxbasierend auf einem einzelnen regulären Ausdruck finden:

>>> 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'

Der reguläre Ausdruck erzeugt ein Tupel von Tagen, Stunden, Minuten als Zeichenfolgen. Das tuple(map(int, ...))konvertiert es in ganze Zahlen. maxwählt das größte dieser Tupel aus, das natürlich Tage stärker als Stunden schwerer als Minuten wiegt.

MisterMiyagi
quelle
1

Ein möglicher Weg:

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

Ausgabe

"14d"
Clément
quelle