Подтвердить что ты не робот

Сортировка словаря по словарям по значению

У меня есть этот словарь:

statuses = {
            'pending' : {'status_for':'all', 'position':1},
            'cancelled' : {'status_for':'all','position':2},
            'approved' : {'status_for':'owner', 'position':1},
            'rejected - owner' : {'status_for':'owner', 'position':2},
            'accepted' : {'status_for':'dev', 'position':1},
            'rejected - developer' : {'status_for':'dev', 'position':3},
            'closed' : {'status_for':'dev', 'position':5},
            }

У меня также есть функция, чтобы вытащить все значения status_for либо owner, либо dev, которые выглядят так и помещают их в PyQt QComboBox:

for s in statuses:
            if statuses[s]['status_for'] == "dev" or statuses[s]['status_for'] == "all":
                cb_developer_status.addItem(s.capitalize(), s)   

Я хотел бы заказать их по значению position. Каков хороший способ сделать это, так что, когда я заполняю combobox, у меня есть это в предопределенном порядке?

Я понимаю, что вышеприведенный фрагмент проверяет как "dev", так и "all", мое предположение прямо сейчас состоит в том, что мне пришлось бы дважды прокручивать словарь, чтобы получить два отдельных блока в желаемом порядке (т.е. "все" появляется перед "dev" ).

Я видел этот пост, но я не уверен, как преобразовать этот ответ в нечто, что это словарь словарей.

4b9b3361

Ответ 1

Что-то вроде этой работы? Подобно сообщению, которое вы связали, для функции пользовательского порядка сортировки используется key функция sorted. iteritems() возвращает кортеж (key, value), поэтому он передается в lambda (x, y): y['position'], где y['position'] - это значение (ваш вложенный словарь, введенный по статусу), а position - это элемент, по которому вы хотите сортировать.

In [35]: statuses = {
            'pending' : {'status_for':'all', 'position':1},
            'cancelled' : {'status_for':'all','position':2},
            'approved' : {'status_for':'owner', 'position':1},
            'rejected - owner' : {'status_for':'owner', 'position':2},
            'accepted' : {'status_for':'dev', 'position':1},
            'rejected - developer' : {'status_for':'dev', 'position':3},
            'closed' : {'status_for':'dev', 'position':5},
            }

In [44]: for s in sorted(statuses.iteritems(), key=lambda (x, y): y['position']):
   ....:     print s
   ....:
   ....:
('accepted', {'position': 1, 'status_for': 'dev'})
('approved', {'position': 1, 'status_for': 'owner'})
('pending', {'position': 1, 'status_for': 'all'})
('rejected - owner', {'position': 2, 'status_for': 'owner'})
('cancelled', {'position': 2, 'status_for': 'all'})
('rejected - developer', {'position': 3, 'status_for': 'dev'})
('closed', {'position': 5, 'status_for': 'dev'})

Ответ 2

In [232]: statuses = {                                                                  
            'pending' : {'status_for':'all', 'position':1},
            'cancelled' : {'status_for':'all','position':2},
            'approved' : {'status_for':'owner', 'position':1},
            'rejected - owner' : {'status_for':'owner', 'position':2},
            'accepted' : {'status_for':'dev', 'position':1},
            'rejected - developer' : {'status_for':'dev', 'position':3},
            'closed' : {'status_for':'dev', 'position':5},
            }

In [235]: sorted(statuses,key=lambda x:statuses[x]['position'])
Out[235]: 
['accepted',
 'approved',
 'pending',
 'rejected - owner',
 'cancelled',
 'rejected - developer',
 'closed']

или используя operator.getitem():

In [260]: from operator import *

In [261]: sorted(statuses.items(),key=lambda x:getitem(x[1],'position'))
Out[261]: 
[('accepted', {'position': 1, 'status_for': 'dev'}),
 ('approved', {'position': 1, 'status_for': 'owner'}),
 ('pending', {'position': 1, 'status_for': 'all'}),
 ('rejected - owner', {'position': 2, 'status_for': 'owner'}),
 ('cancelled', {'position': 2, 'status_for': 'all'}),
 ('rejected - developer', {'position': 3, 'status_for': 'dev'}),
 ('closed', {'position': 5, 'status_for': 'dev'})]