Mam więc słownik, który wygląda tak, gdy drukujeję:

{'10': -10, 'ZT21': 14, 'WX21': 12, '2': 15, '5': -3, 'UM': -25}

Chcę to posortować w sposób niestandardowy, co zdefiniuję. Powiedzmy sposób, w jaki chcę, aby go posortował (według klawisza) jest ZT21, 10, WX21, UM, 5, 2.

Czy ktoś wie, jak przejść do uporządkowania słownika w predefiniowanym / niestandardowym sposobie? Co robię, to zdobyć ten słownik z bazy danych, a może wyjść z ponad 20 kluczy, z których wszystkie mają określone zamówienie. Zamówienie jest zawsze ustawione, ale czasami niektóre klucze / wartości nie byłyby w słowniku. Więc też może się zdarzyć:

{'ZT21': 14, 'WX21': 12, '2': 15, '5': -3, 'UM': -25}

Posortowany (według klawisza) jest ZT21, 10, WX21, UM, 5, 2.

Więc 10 nie jest tam w tym przykładzie, ale potrzebuję sortowania, jest nadal taki sam, 10 po prostu będzie nieobecny.

Jakieś pomysły?

13
user1610719 20 sierpień 2012, 05:55

5 odpowiedzi

Najlepsza odpowiedź

Słowniki w Pythonie są nieuporządkowane. Możesz uzyskać wyniki, które potrzebujesz jako list

>>> d = {'10': -10, 'ZT21': 14, 'WX21': 12, '2': 15, '5': -3, 'UM': -25}
>>> keyorder = ['ZT21', '10', 'WX21', 'UM', '5', '2']
>>> sorted(d.items(), key=lambda i:keyorder.index(i[0]))
[('ZT21', 14), ('10', -10), ('WX21', 12), ('UM', -25), ('5', -3), ('2', 15)]

Lub jako uporządkowany

>>> from collections import OrderedDict
>>> OrderedDict(sorted(d.items(), key=lambda i:keyorder.index(i[0])))
OrderedDict([('ZT21', 14), ('10', -10), ('WX21', 12), ('UM', -25), ('5', -3), ('2', 15)])

Jeśli robisz dużo z nich, będzie bardziej wydajny do użycia dict dla pliku

>>> keyorder = {k:v for v,k in enumerate(['ZT21', '10', 'WX21', 'UM', '5', '2'])}
>>> OrderedDict(sorted(d.items(), key=lambda i:keyorder.get(i[0])))
OrderedDict([('ZT21', 14), ('10', -10), ('WX21', 12), ('UM', -25), ('5', -3), ('2', 15)])
43
John La Rooy 20 sierpień 2012, 02:50

Możesz sortować go za pomocą zamówienia i określając zamówienie zamówienia.

def customsort(dict1 , key_order):
    items = [dict1[k] if k in dict1.keys() else 0 for k in key_order] 
    sorted_dict = OrderedDict()
    for i in range(len(key_order)):
        sorted_dict[key_order[i]] = items[i]
    return sorted_dict
key_order = [ "monday" ,"tuesday" ,"wednesday" ,"thursday" ,"friday" ,"saturday"]
dict1 ={"monday" : 10 , "thursday" :12 , "wednesday" : 34}
sorted_dicti = customsort(dict1,key_order)
print(sorted_dicti)

Customsort () Sortuje Słownik (DICT1) według kolejności (Key_order) przekazywany przez użytkownika.

items = [dict1[k] if k in dict1.keys() else 0 for k in key_order] 

Sprawdzi to, czy podany klawisz jest w DICT1, jeśli jest tam, następnie umieść wartość określoną w DICT1 ELSE WARTOŚĆ AS 0.

OrderedDict([('monday', 10), ('tuesday', 0), ('wednesday', 34), ('thursday', 12), ('friday', 0), ('saturday', 0)])
3
Nikita Maru 23 lipiec 2018, 06:42

Nie możesz. Zamiast tego użyj collections.OrderedDict.

2
Ignacio Vazquez-Abrams 20 sierpień 2012, 01:57

Słowniki są z natury nieuporządkowane, więc nie możesz bezpośrednio posortować słownika. Możesz sortować parę / parami parami, sortując someDict.items() i przechodzenie w funkcji klucza, tak jakbyś kiedyś sortował coś innego, ale otrzymasz posortowaną listę, a nie słownik. Zobacz poprzednie pytania dotyczące sortowania słownika: Python: Sortowanie słownika list i < href = "https://stackoverflow.com/questions/11753758/dictionary-sorting-by-ey-Length"> Sortowanie słownika według długości klucza na przykład.

1
Community 23 maj 2017, 11:47

Miałem dokładnie ten sam problem i opracowałem lekkie rozwiązanie ogólne:

from collections import OrderedDict

def make_custom_sort(orders):
    orders = [{k: -i for (i, k) in enumerate(reversed(order), 1)} for order in orders]
    def process(stuff):
        if isinstance(stuff, dict):
            l = [(k, process(v)) for (k, v) in stuff.items()]
            keys = set(stuff)
            for order in orders:
                if keys.issuperset(order):
                    return OrderedDict(sorted(l, key=lambda x: order.get(x[0], 0)))
            return OrderedDict(sorted(l))
        if isinstance(stuff, list):
            return [process(x) for x in stuff]
        return stuff
    return process

Najpierw utworzysz instancję funkcji sortowania zamówienia zamówienia:

custom_sort = make_custom_sort([ ['ZT21', '10', 'WX21', 'UM', '5', '2'] ])

Teraz rzeczywiste sortowanie:

result = custom_sort(my_dataset)

Brakujące klucze są odrzucane na końcu w nieokreślonym porządku. Zauważ, że to zamknięcie jest rekurencyjne. Jak wskazano przez podwójne wsporniki, można określić tyle zamówień sortowania, ponieważ różne słowniki zagnieżdżone w strukturze będą wymagały.

Projekt na temat GitHub: https://github.com/laowantong/customsort

0
Aristide 29 lipiec 2014, 20:17