2017-10-12 2 views
-1

Mein Code ist:Wie sortiere ich eine Liste von Wörterbüchern nach relativen Datumswerten?

a = {"key1": 5 , "key2": "8 hours ago", "key3": 2} 
b = {"key1": 7 , "key2": "42 hours ago", "key3": 9} 
c = {"key1": 6 , "key2": "1 hour ago", "key3": 1} 
undecorated = [a, b, c] 

undecorated.sort(key=operator.itemgetter('key2')) 

Ergebnis ist:

[ 
{"key1": 6 , "key2": "1 hour ago", "key3": 1} 
{"key1": 7 , "key2": "42 hours ago", "key3": 9} 
{"key1": 5 , "key2": "8 hours ago", "key3": 2} 
] 

aber Ergebnis Notwendigkeit:

[ 
{"key1": 6 , "key2": "1 hour ago", "key3": 1} 
{"key1": 5 , "key2": "8 hours ago", "key3": 2} 
{"key1": 7 , "key2": "42 hours ago", "key3": 9} 
] 
+3

Nein, ist der Wert ein String ist, und Strings lexikographisch sortiert. –

Antwort

8

Wenn die Werte für key2 als pr als reguläre sind esented hier können Sie tun:

undecorated.sort(key=lambda d: int(d['key2'].split()[0])) 
+0

Dies wird keine Werte wie "vor 1 Stunde" und "2 Minuten" richtig sortieren. Dazu müssten Sie [einen generischen Parser verwenden] (https://stackoverflow.com/a/46713151/244297). –

+0

@EugeneYarmash Wahr, aber wenn die Werte so allgemein sind, sollte das OP eine größere Auswahl an Beispielen enthalten. Dies funktioniert für die dargestellte Eingabe und ohne zusätzliche Pakete. Und ich ** habe bereits meine Lösung für diese Einschränkungen im Intro-Satz qualifiziert;) – schwobaseggl

0

Aufgrund der Vergleichs Schlüssel ein wenig kompliziert ist, ziehe ich es eine Funktion machen eher als ein Lambda, das enthält dosen außer versuchen, und ist besser lesbar:

a = {"key1": 5, "key2": "8 hours ago", "key3": 2} 
b = {"key1": 7, "key2": "42 hours ago", "key3": 9} 
c = {"key1": 6, "key2": "1 hour ago", "key3": 1} 
undecorated = [a, b, c] 


def compare_key(my_dict): 
    value = my_dict.get('key2') 
    try: 
     result = int(value.split()[0]) 
    except: 
     result = 0 
    return result 


undecorated.sort(key=compare_key) 

print(undecorated) 
+1

Bloßes 'außer' sind nicht wirklich guter Stil. Es könnte auch nützlich sein, die Gründe dafür zu erklären, die Fehler am Anfang zu setzen (mit '0'). – MSeifert

+0

Sie haben recht, hier ist nur eine Demo, die Ausnahme sollte genauer sein, aber hier ist für Demo. –

3

Wie bereits in den Kommentaren erklärt, da Ihre Vergleichsschlüssel Strings sind, werden sie lexikographisch verglichen. Sie könnten das dateparser Modul (pip install dateparser) verwenden, um die Saiten zu datetime Objekte zu analysieren, die richtig vergleichen:

>>> from dateparser import parse 
>>> undecorated.sort(key=lambda x: parse(x["key2"]), reverse=True) 
>>> undecorated 
[{'key1': 6, 'key2': '1 hour ago', 'key3': 1}, {'key1': 5, 'key2': '8 hours ago', 'key3': 2}, {'key1': 7, 'key2': '42 hours ago', 'key3': 9}] 
Verwandte Themen