web-dev-qa-db-ja.com

辞書の辞書を値で並べ替える

私はこの辞書を持っています:

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},
            }

ownerまたはdevのすべてのstatus_for値をプルして、PyQtQComboBoxに入れる関数もあります。

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

ただし、これらをposition値で並べ替えたいと思います。これを行うための良い方法は何ですか?コンボボックスでデータを入力するときに、事前定義された順序でそれを取得できますか?

上記のスニペットは「dev」と「all」の両方をチェックしていることに気付きました。今のところ、2つの別々のブロックを希望の順序で取得するには、辞書を2回ループする必要があると想定しています(つまり、「all」 'dev'の前に表示されます)。

この投稿 を見ましたが、この回答を辞書の辞書に変換する方法がわかりません。

18
Andy

このようなものは機能しますか?リンクした投稿と同様に、これはkeysorted関数を使用して、カスタムの並べ替え順序を提供します。 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'})
_
26
RocketDonkey
_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'})]
_
9