2015-08-27 63 views
0

排序我有一個列表蟒字典由列表

category = ['Toy','Cloth','Food','Auto'] 

也有我的字典(其中第一A,B,C ...的項目名稱,在每個列表中第一個元素類別,第二個是我想這個價格。

inventory = {'A':['Food', 5], 'B':['Food', 6], 
      'C':['Auto', 5], 'D':['Cloth', 14], 
      'E':['Toy',19], 'F':['Cloth', 13], 'G':['Toy',20], 'H':['Toy',11]} 

要在列表中的類別的順序先進行排序,然後其次,我想他們由價格來排序(當類別順序維護),使得結果看起來像這樣...

inventory_sorted = {'G':['Toy',20],'E':['Toy',19], 'H':['Toy',11], 'D':['Cloth', 14], 
        'F':['Cloth', 13], 'B':['Food', 6],'A':['Food', 5],'C':['Auto', 5],} 

能否請您提供兩步流程,首先是關於根據清單類別進行排序,其次是關於通過保留類別排序的價格對價格進行排序(相反)。如果您使用的是Lambda,請給我一點敘述,以便我能更好地理解。我是Lamda表達新手。非常感謝你

+3

無法排序字典。他們是無序的。你將不得不改變數據結構。 –

+1

你可以試試OrderedDict。 –

回答

3

你不能排序Python dict對象,因爲它們沒有排序。最多可以產生一個排序的(鍵值)對序列。如果您想要包含訂單的映射,則可以將這些對供應給collections.OrderedDict() object

將您的category訂單轉換爲映射以獲得訂單,然後在排序關鍵字和價格中使用該訂單。因爲你希望你的價格排序在降序順序,你需要返回價格:

cat_order = {cat: i for i, cat in enumerate(category)} 
inventory_sorted = sorted(inventory.items(), 
          key=lambda i: (cat_order[i[1][0]], -i[1][1])) 

i參數傳遞的每個鍵 - 值對; i[1]然後是價值,i[1][0]的類別,i[1][1]的價格。

這將產生鍵值對指定的順序:

>>> category = ['Toy','Cloth','Food','Auto'] 
>>> inventory = {'A':['Food', 5], 'B':['Food', 6], 
...   'C':['Auto', 5], 'D':['Cloth', 14], 
...   'E':['Toy',19], 'F':['Cloth', 13], 'G':['Toy',20], 'H':['Toy',11]} 
>>> cat_order = {cat: i for i, cat in enumerate(category)} 
>>> sorted(inventory.items(), key=lambda i: (cat_order[i[1][0]], -i[1][1])) 
[('G', ['Toy', 20]), ('E', ['Toy', 19]), ('H', ['Toy', 11]), ('D', ['Cloth', 14]), ('F', ['Cloth', 13]), ('B', ['Food', 6]), ('A', ['Food', 5]), ('C', ['Auto', 5])] 
>>> from pprint import pprint 
>>> pprint(_) 
[('G', ['Toy', 20]), 
('E', ['Toy', 19]), 
('H', ['Toy', 11]), 
('D', ['Cloth', 14]), 
('F', ['Cloth', 13]), 
('B', ['Food', 6]), 
('A', ['Food', 5]), 
('C', ['Auto', 5])] 

OrderedDict()對象直接接受這個順序:

>>> from collections import OrderedDict 
>>> OrderedDict(sorted(inventory.items(), key=lambda i: (cat_order[i[1][0]], -i[1][1]))) 
OrderedDict([('G', ['Toy', 20]), ('E', ['Toy', 19]), ('H', ['Toy', 11]), ('D', ['Cloth', 14]), ('F', ['Cloth', 13]), ('B', ['Food', 6]), ('A', ['Food', 5]), ('C', ['Auto', 5])]) 
2

你可以種用下面的得到這樣的:

sorted(inventory.items(), key=lambda t: category.index(t[1][0])) 

這是可行的,因爲:

  • inventory.items()把你的詞典到元組的列表,可以保留基於這樣t[1][0]出現在category列表的順序
  • key功能訂單,
  • t將會像('G', ('Toy', 20))所以t[1]('Toy', 20)t[1][0]'Toy'

但是,您不能從此回到標準dict(即使它很容易),因爲您會再次失去您的訂購,導致排序無意義。所以你要麼必須以這種格式處理數據,要麼像前面提到的那樣使用類似collections.OrderedDict的東西。

0

這樣做的另一種完全不同的方式,這是相當強大的,是

  1. 使用Python類,以使數據結構,
  2. 存放在列表中的數據
  3. 排序列表與關鍵= attrgetter( '變量')

下面的示例代碼片段:

class Item: 
    def __init__(self,label,category,number): 
     self.label = label 
     self.category = category 
     self.number = number 
    def __repr__(self): 
     return "Item(%s,%s,%d)"%(self.label,self.category,self.number) 
    def __str__(self): 
     return "%s: %s,%d"%(self.label,self.category,self.number) 

inventory = [] 
inventory.append(Item("A","Food",5)) 
inventory.append(Item("B","Food",6)) 
inventory.append(Item("C","Auto",5)) 
inventory.append(Item("D","Cloth",14)) 
inventory.append(Item("E","Toy",19)) 
inventory.append(Item("F","Cloth",13)) 
inventory.append(Item("G","Toy",20)) 
inventory.append(Item("H","Toy",11)) 

inventory.sort(key=attrgetter('number'),reverse=True) 
inventory.sort(key=attrgetter('category')) 

這樣做的好處是,排序的目的是保持排序順序,所以調用它兩次(如上所述)允許您按類別排序,但按數字排序其次。您可以根據需要爲此排序鍵。

您還可以將任何其他信息添加到您的項目中。

0
categories = ['Toy','Cloth','Food','Auto'] 

inventory = {'A':['Food', 5], 'B':['Food', 6], 
      'C':['Auto', 5], 'D':['Cloth', 14], 
      'E':['Toy',19], 'F':['Cloth', 13], 'G':['Toy',20], 'H':['Toy',11]} 

from collections import OrderedDict 

inventory_sorted = OrderedDict() 

for category in categories: 
    same_category = [(key, num) for key, (cat, num) in inventory.items() if cat == category] 

    for (key, num) in sorted(same_category, key=lambda (_, num): num, reverse=True): 
     inventory_sorted[key] = [category, num] 

for key, value in inventory_sorted.items(): 
    print key, value 

由於dictionaries是無序的,我們將使用OrderedDict,以實現自己的目標。

工作原理:

same_category是一個簡單的列表理解,如果他們是同一類別的電流回路類別可過濾項目,將形成由(鍵,NUM)對元組的列表。

然後我們使用數字,這確實這是key=lambda (_, num): num,這拆包元組,丟棄使用_關鍵行排序這個新的列表,和排序num,我們扭轉它,所以它首先展示高的數字。

然後我們將這些[category, num]對中的每一對添加到key中的OrderedDict inventory_sorted

結果:

G ['Toy', 20] 
E ['Toy', 19] 
H ['Toy', 11] 
D ['Cloth', 14] 
F ['Cloth', 13] 
B ['Food', 6] 
A ['Food', 5] 
C ['Auto', 5]