sorted()与L.sort()

在python中,经常遇到对列表(list)进行排序的需求,而sorted是内置排序函数,那么二者的区别是什么呢?具体怎么用来对列表进行排序呢?看似简单,但是当列表结构比较复杂时,初学者难免会疑惑甚至用错(比如我就是其中一员,感觉是照搬都没一次性搞对),那么这里就简述一下其用法。

  • 主要区别
    sort:修改原列表
    sorted:产生一个新的列表 (sorted() 函数对所有可迭代的对象进行排序操作。)

1. 简单列表

创建一个列表a

a=[4,3,6,8,7,34]

直接使用sorted方法,返回一个列表b,b就是排序好了的

b=sorted(a)
print b

结果如下:

[3, 4, 6, 7, 8, 34]
  • 即返回由小到大排序的结果。

2. 元组构成的列表

==== 当列表是由元祖构成时,处理起来就要稍加注意:

====

  • sorted语法
sorted(iterable[, cmp[, key[, reverse]]])

排序前的blockList为如下列表:

blockList=[{
	"Elements": [{
		"AdvanceWidth": 102.5,
		"Point": "895,320",
		"Character": "抚"
	},
	{
		"AdvanceWidth": 92.5,
		"Point": "983,322",
		"Character": "州"	
	}],
	"BlockText": "抚州"
},
{
	"Elements": [{
		"AdvanceWidth": 100.0,
		"Point": "851,405",
		"Character": "南"
	}],
	"BlockText": "南"
},
{
	"Elements": [{
		"AdvanceWidth": 82.05128205128206,
		"Point": "947,405",
		"Character": "昌"
	},
	{
		"AdvanceWidth": 98.75,
		"Point": "1025,405",
		"Character": "大"
	}],
	"BlockText": "昌大"
},
{
	"Elements": [{
		"AdvanceWidth": 101.50375939849624,
		"Point": "1753,390",
		"Character": "放"
	},
	{
		"AdvanceWidth": 102.98507462686567,
		"Point": "1894,391",
		"Character": "射"
	}],
	"BlockText": "放射"
}]

=== 对其进行排序:是按照每组中的第一个元素的x坐标,进行组排序

blockList.sort(key=lambda  x:float(x['Elements'][0]['Point'].split(',')[0]))

则排序后为:

[{
	"Elements": [{
		"AdvanceWidth": 100.0,
		"Point": "851,405",
		"Character": "南"
	}],
	"BlockText": "南"
},
{
	"Elements": [{
		"AdvanceWidth": 102.5,
		"Point": "895,320",
		"Character": "抚"
	},
	{
		"AdvanceWidth": 92.5,
		"Point": "983,322",
		"Character": "州"
	}],
	"BlockText": "抚州"
},
{
	"Elements": [{
		"AdvanceWidth": 82.05128205128206,
		"Point": "947,405",
		"Character": "昌"
	},
	{
		"AdvanceWidth": 98.75,
		"Point": "1025,405",
		"Character": "大"
	}],
	"BlockText": "昌大"
},
{
	"Elements": [{
		"AdvanceWidth": 101.50375939849624,
		"Point": "1753,390",
		"Character": "放"
	},
	{
		"AdvanceWidth": 102.98507462686567,
		"Point": "1894,391",
		"Character": "射"
	}],
	"BlockText": "放射"
}]

即按每组中(x为包含Elements和BlockList两个键值的字典,x['Elements']取每个的Elements键,x['Elements'[0]则定位到第一个元素)第一个元素的x坐标排序。

参数说明

**iterable **-- 可迭代对象。

cmp -- 比较的函数,这个具有两个参数,参数的值都是从可迭代对象中取出,此函数必须遵守的规则为,大于则返回1,小于则返回-1,等于则返回0。

key -- 主要是用来进行比较的元素,只有一个参数,具体的函数的参数就是取自于可迭代对象中,指定可迭代对象中的一个元素来进行排序。

reverse -- 排序规则,reverse = True 降序 , reverse = False 升序(默认)。

返回值

返回重新排序的列表。

=== 实例1:

L=[('b',2),('a',1),('c',3),('d',4)]

1:利用cmp函数

sorted(L, cmp=lambda x,y:cmp(x[1],y[1]))

排序结果:

[('a', 1), ('b', 2), ('c', 3), ('d', 4)]

2:利用key

sorted(L, key=lambda x:x[1])

排序结果:

[('a', 1), ('b', 2), ('c', 3), ('d', 4)]

=== 实例2:

students = [('john', 'A', 15), ('jane', 'B', 12), ('dave', 'B', 10)]

sorted(students, key=lambda s: s[2])

排序结果:

[('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]

降序排列

sorted(students, key=lambda s: s[2], reverse=True)

排序结果:

[('john', 'A', 15), ('jane', 'B', 12), ('dave', 'B', 10)]

小结

====

key 和 reverse 比一个等价的 cmp 函数处理速度要快。这是因为对于每个列表元素,cmp 都会被调用多次,而 key 和 reverse 只被调用一次。