2012-07-05 144 views
1

我有一本字典,看起來像這樣:排序字典值

myDict = { 
    'SER12346': {'serial_num': 'SER12346', 'site_location': 'North America'}, 
    'ABC12345': {'serial_num': 'ABC12345', 'site_location': 'South America'}, 
    'SER12345': {'serial_num': 'SER12345', 'site_location': 'North America'}, 
    'SER12347': {'serial_num': 'SER12347', 'site_location': 'South America'}, 
    'ABC12346': {'serial_num': 'ABC12346', 'site_location': 'Europe'} 
} 

我的目標是解決這字典由site_location和每個子詞典的serial_num

使用代碼我在這個問題上找到 - Sort a dictionary of dictionaries python - 我能得到它的排序,但它並不完全是什麼我期待。

這是我的代碼:

import pprint 
items = ((k, k2, v) for k in myDict for k2, v in myDict[k].items()) 
ordered = sorted(items, key=lambda x:x[-1], reverse=False) 
pprint.pprint(ordered) 

這是結果我得到:

[('ABC12346', 'site_location', 'Europe'), 
('SER12345', 'site_location', 'North America'), 
('SER12346', 'site_location', 'North America'), 
('SER12347', 'site_location', 'South America'), 
('ABC12345', 'site_location', 'South America'), 
('ABC12346', 'serial_num': 'ABC12346'), 
('SER12345', 'serial_num': 'SER12345'), 
('SER12346', 'serial_num': 'SER12346'), 
('SER12347', 'serial_num': 'SER12347'), 
('ABC12345', 'serial_num': 'ABC12345')] 

我期待更多的東西像這樣雖然:

{ 
    'ABC12346': {'serial_num': 'ABC12346', 'site_location': 'Europe'} 
    'SER12345': {'serial_num': 'SER12345', 'site_location': 'North America'}, 
    'SER12346': {'serial_num': 'SER12346', 'site_location': 'North America'}, 
    'SER12347': {'serial_num': 'SER12347', 'site_location': 'South America'}, 
    'ABC12345': {'serial_num': 'ABC12345', 'site_location': 'South America'}, 
} 

實際的結果是分離序列號和站點位置。我想將它們放在排序的對象中。我怎樣才能做到這一點?

+2

最後一個片段是不是有效的Python - 你不能在列表中的鍵。 – georg 2012-07-05 14:17:09

+0

@ thg435,你是對的。這是缺乏轉變。這應該是一本字典,但我會很滿意那種以這種方式訂購的東西。元組或類似的列表可以和我在一起。 – Andy 2012-07-05 14:25:21

+0

@Andy如果要排序的字典結構使用OrderedDict如下圖所示 – 2012-07-05 14:48:44

回答

4

這是你想要的嗎?

dicts = [{k: v} for (k,v) in myDict.items()] 
dicts.sort(key=lambda d: (d.values()[0]['site_location'], d.values()[0]['serial_num'],)) 

輸出做:

import pprint 
pprint.pprint(dicts) 

是:

[{'ABC12346': {'serial_num': 'ABC12346', 'site_location': 'Europe'}}, 
{'SER12345': {'serial_num': 'SER12345', 'site_location': 'North America'}}, 
{'SER12346': {'serial_num': 'SER12346', 'site_location': 'North America'}}, 
{'ABC12345': {'serial_num': 'ABC12345', 'site_location': 'South America'}}, 
{'SER12347': {'serial_num': 'SER12347', 'site_location': 'South America'}}] 

編輯:我本來打算對你的解答輸出格式,但是這可能會更有意義:

dicts = myDict.items() 
dicts.sort(key=lambda (k,d): (d['site_location'], d['serial_num'],)) 

輸出:

[('ABC12346', {'serial_num': 'ABC12346', 'site_location': 'Europe'}), 
('SER12345', {'serial_num': 'SER12345', 'site_location': 'North America'}), 
('SER12346', {'serial_num': 'SER12346', 'site_location': 'North America'}), 
('ABC12345', {'serial_num': 'ABC12345', 'site_location': 'South America'}), 
('SER12347', {'serial_num': 'SER12347', 'site_location': 'South America'})] 
+0

在元組例子,我怎麼能排序的'site_location'的序列號呢? – Andy 2012-07-05 14:46:46

+0

@安迪:哦,我的錯誤,編輯它。它應該是'(d [ 'SITE_LOCATION'],d [ 'SERIAL_NUM'])','未(K,d [ 'SITE_LOCATION'],d [ 'SERIAL_NUM'])' – Claudiu 2012-07-05 14:50:06

0

我有cmp一個解決方案(我想你必須使用,因爲我們採用2個鍵的組合),但它不是真的很漂亮,我想這可以改進:

>>> pprint(sorted(myDict.items(), cmp=lambda x, y: cmp((x[1]['site_location'], x[1]['serial_num']), (y[1]['site_location'], y[1]['serial_num'])))) 
[('ABC12346', {'serial_num': 'ABC12346', 'site_location': 'Europe'}), 
('SER12345', {'serial_num': 'SER12345', 'site_location': 'North America'}), 
('SER12346', {'serial_num': 'SER12346', 'site_location': 'North America'}), 
('ABC12345', {'serial_num': 'ABC12345', 'site_location': 'South America'}), 
('SER12347', {'serial_num': 'SER12347', 'site_location': 'South America'})] 
+1

使用'key'乾淨多。所有你正在做的基本上是做'cmp'這兩個值是'key'將返回,除了值不獲取緩存(因爲他們與'key'做)。它工作的原因是元組按照您認爲的方式進行比較,所以如果'key'返回一個元組,它會比較多個值。 – Claudiu 2012-07-05 14:25:18

1

字典不保存物品的順序 - 因此無法排序。如果您想要顯示已排序的字典,則需要創建已排序的列表,然後將其插入到OrderedDict類中。下面的代碼片段說明了這一點:

from collections import OrderedDict 

myDict = { 
    'SER12346': {'serial_num': 'SER12346', 'site_location': 'North America'}, 
    'ABC12345': {'serial_num': 'ABC12345', 'site_location': 'South America'}, 
    'SER12345': {'serial_num': 'SER12345', 'site_location': 'North America'}, 
    'SER12347': {'serial_num': 'SER12347', 'site_location': 'South America'}, 
    'ABC12346': {'serial_num': 'ABC12346', 'site_location': 'Europe'} 
} 

def sortfun(d): 
    return (d[1]['site_location'], d[1]['serial_num']) 

skv = sorted(myDict.iteritems(), key=sortfun) 
sorted_dict = OrderedDict(skv) 

print sorted_dict 
+0

你可以從'sortfun'返回一個元組 – Claudiu 2012-07-05 14:29:50

+0

@Claudiu好點 - 看起來更乾淨 - 更新上面 – 2012-07-05 14:31:27

1
>>> import pprint 
>>> dic=myDict.items() 
>>> dic.sort(key=lambda x:(x[1]['site_location'],x[1]['serial_num'])) 
>>> pprint.pprint([{k:v} for k,v in dic]) 
[{'ABC12346': {'serial_num': 'ABC12346', 'site_location': 'Europe'}}, 
{'SER12345': {'serial_num': 'SER12345', 'site_location': 'North America'}}, 
{'SER12346': {'serial_num': 'SER12346', 'site_location': 'North America'}}, 
{'ABC12345': {'serial_num': 'ABC12345', 'site_location': 'South America'}}, 
{'SER12347': {'serial_num': 'SER12347', 'site_location': 'South America'}}]