python dict 排序


我們知道Python的內置dictionary數據類型是無序的,通過key來獲取對應的value。可是有時我們需要對dictionary中 的item進行排序輸出,可能根據key,也可能根據value來排。到底有多少種方法可以實現對dictionary的內容進行排序輸出呢?下面摘取了 一些精彩的解決辦法。 

python對容器內數據的排序有兩種,一種是容器自己的sort函數,一種是內建的sorted函數。

sort函數和sorted函數唯一的不同是,sort是在容器內(in-place)排序,sorted生成一個新的排好序的容器。

對於一個簡單的數組 L=[5,2,3,1,4].

(1)  L.sort(),  sort(comp=None, key=None, reverse=False)   --> in place sort

(2) sorted(iterable, cmp=None, key=None, reverse=False)  --> return a new sorted list

  • cmp specifies a custom comparison function of two arguments (iterable elements) which should return a negative, zero or positive number depending on whether the first argument is considered smaller than, equal to, or larger than the second argument: cmp=lambda x,y: cmp(x.lower(), y.lower()). The default value is None.
  • key specifies a function of one argument that is used to extract a comparison key from each list element: key=str.lower. The default value is None (compare the elements directly).
  • reverse is a boolean value. If set to True, then the list elements are sorted as if each comparison were reversed.

In general, the key and reverse conversion processes are much faster than specifying an equivalent cmp function. This is because cmp is called multiple times for each list element while key and reverse touch each element only once. Use functools.cmp_to_key() to convert an old-style cmp function to a key function.

The built-in sorted() function is guaranteed to be stable. A sort is stable if it guarantees not to change the relative order of elements that compare equal — this is helpful for sorting in multiple passes (for example, sort by department, then by salary grade).

算法的穩定性,基數排序正確性的保證,在低位排序好后,相同的高位排在一起,但要保證之前的地位相對順序不變。

 

1 按照Key值排序

#最簡單的方法,這個是按照key值排序: 
def sortedDictValues1(adict): 
items = adict.items() items.sort() return [value for key, value in items] #又一個按照key值排序,貌似比上一個速度要快點 def sortedDictValues2(adict): keys = adict.keys() keys.sort() return [dict[key] for key in keys] #還是按key值排序,據說更快。。。而且當key為tuple的時候照樣適用 def sortedDictValues3(adict): keys = adict.keys() keys.sort() return map(adict.get, keys) #一行語句搞定: [(k,di[k]) for k in sorted(di.keys())] 

#用sorted函數的key參數(func)排序: 
#按照key進行排序 
print sorted(dict1.items(), key=lambda d: d[0])

 

2 按照value值排序

#來一個根據value排序的,先把item的key和value交換位置放入一個list中,再根據list每個元素的第一個值,即原來的value值,排序: 
def sort_by_value(d): 
items=d.items() backitems=[[v[1],v[0]] for v in items] backitems.sort() return [ backitems[i][1] for i in range(0,len(backitems))] #還是一行搞定: [ v for v in sorted(di.values())] #用lambda表達式來排序,更靈活: sorted(d.items(), lambda x, y: cmp(x[1], y[1])), 或反序: sorted(d.items(), lambda x, y: cmp(x[1], y[1]), reverse=True) #用sorted函數的key參數(func)排序: # 按照value進行排序 print sorted(dict1.items(), key=lambda d: d[1]) 

 

3 擴展用法:Key Function

從Python2.4開始,list.sort() 和 sorted() 都增加了一個 ‘key’ 參數用來在進行比較之前指定每個列表元素上要調用的函數。

例1: 不區分大小寫的字符串比較排序:

>>> sorted("This is a test string from Andrew".split(), key=str.lower)
['a', 'Andrew', 'from', 'is', 'string', 'test', 'This']

key應該是一個函數,其接收一個參數,並且返回一個用於排序依據的key。其執行效率很高,因為對於輸入記錄key function能夠准確的被調用。

例2 對於復雜的對象,使用對象的下標作為key:

>>> student_tuples = [
...     ('john', 'A', 15), ... ('jane', 'B', 12), ... ('dave', 'B', 10), ... ] >>> sorted(student_tuples, key=lambda student: student[2]) # sort by age [('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]

例3 使用對象的屬性進行操作:

>>> class Student:
...     def __init__(self, name, grade, age): ... self.name = name ... self.grade = grade ... self.age = age ... def __repr__(self): ... return repr((self.name, self.grade, self.age)) >>> >>> student_objects = [ ... Student('john', 'A', 15), ... Student('jane', 'B', 12), ... Student('dave', 'B', 10), ... ] >>> sorted(student_objects, key=lambda student: student.age) # sort by age [('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]

當列表里面每一個元素不止一個元素(比如:列表里面,元素為元祖類型),我們除了想對第一個關鍵字排序之外,還想在第一次的基礎上面根據第二個關鍵字進行排序:

>>> list2 = [('d', 3), ('a', 5), ('d', 1), ('c', 2), ('d', 2)]
>>> list2 [('d', 3), ('a', 5), ('d', 1), ('c', 2), ('d', 2)] >>> list2.sort() >>> list2 [('a', 5), ('c', 2), ('d', 1), ('d', 2), ('d', 3)] >>> list3 = [('d', 3), ('a', 5), ('d', 1), ('c', 2), ('d', 2)] >>> sorted(list3, key = lambda x:(x[0],x[1])) [('a', 5), ('c', 2), ('d', 1), ('d', 2), ('d', 3)]

 

4 Operator Module Functions

這個操作模塊有:

  • operator.itemgetter()   ----- 通過下標
  • operator.attrgetter()   ----- 通過參數
  • operator.methodcaller() -----python 2.5 被引入,下文詳細介紹

使用這幾個函數,對於上面 Key Function 的例子處理起來將會更加的簡便和快速

先一塊介紹 operator.itemgetter() 和 operator.attrgetter() 這倆個,會更加容易理解:

例如:

>>> from operator import itemgetter, attrgetter
>>>
>>> sorted(student_tuples, key=itemgetter(2)) [('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)] >>> >>> sorted(student_objects, key=attrgetter('age')) [('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]

這個操作模塊也允許多層次的進行排序,例如可以先排序 “成績grand” 再排序 “年齡age”

例如:

>>> sorted(student_tuples, key=itemgetter(1,2))
[('john', 'A', 15), ('dave', 'B', 10), ('jane', 'B', 12)] >>> >>> sorted(student_objects, key=attrgetter('grade', 'age')) [('john', 'A', 15), ('dave', 'B', 10), ('jane', 'B', 12)]

現在回過頭來發現,上面在前幾天遇到的問題,可以用這個operator.itemgetter進行解決:

>>> list = [('d',3),('a',5),('d',1),('c',2),('d',2)]
>>> from operator import itemgetter >>> sorted(list, key=itemgetter(0,1)) [('a', 5), ('c', 2), ('d', 1), ('d', 2), ('d', 3)]

但是還是推薦 1.key function 中的方法,因為為了這一個排序而引入一個庫文件,相對來說得不償失。

下面介紹operator.methodcaller() 函數:

這個函數是對某個對象的使用固定參數進行排序,例如:str.count() 函數可以計算每個字符串對象中含有某個參數的個數,那運用這個函數我就可以通過 str.count() 計算出某個字符的個數從而來確定排序的優先級:

>>> from operator import methodcaller
>>> messages = ['critical!!!', 'hurry!', 'standby', 'immediate!!'] >>> sorted(messages, key=methodcaller('count', '!')) ['standby', 'hurry!', 'immediate!!', 'critical!!!']

 

5 python collections

This module implements specialized container datatypes providing alternatives to Python’s general purpose built-in containers, dictlistset, and tuple 

namedtuple()   factory function for creating tuple subclasses with named fields

deque list-like container with fast appends and pops on either end

Counter dict subclass for counting hashable objects

OrderedDict dict subclass that remembers the order entries were added

defaultdict dict subclass that calls a factory function to supply missing values

In addition to the concrete container classes, the collections module provides abstract base classes that can be used to test whether a class provides a particular interface, for example, whether it is hashable or a mapping.

 

參考:

python function: sorted

Python 排序---sort與sorted學習

python dict sorted 排序

Python: sort,sorted,OrderedDict的用法

collections — High-performance container datatypes

collections -- 廖雪峰

-- stackoverflow

How does tuple comparison work in Python 

How do I sort a list of dictionaries by values of the dictionary in Python

How do I sort a dictionary by value

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM