sort data using Python3
list.sort()
与 sorted()
的比较
Python列表具有内置的list.sort()
方法,可以原位修改列表。
python的内置函数sorted()
则可将一个可迭代对象(iterable)构建成一个新的排序列表。
通常较多的使用sorted()
,但是如果用户不需要原始列表,那么则可以考虑使用list.sort()
,因为它的效率稍微高于sorted()
。
iterable主要包括3类:
第一类是所有的序列类型,比如list(列表)、str(字符串)、tuple(元组)。
第二类是一些非序列类型,比如dict(字典)、file(文件)。
第三类是你定义的任何包含__iter__()
或__getitem__()
方法的类的对象。
简单用法
sorted(iterable, key=None, reverse=False) -> new list
List.sort(key=None, reverse=False) -> None
#返回新的列表
>>> sorted([5, 2, 3, 1, 4])
[1, 2, 3, 4, 5]
#原位修改列表
>>> a = [5, 2, 3, 1, 4]
>>> a.sort()
>>> a
[1, 2, 3, 4, 5]
key-function
参数:key parameter
list.sort()
和sorted()
都有一个键参数,用列表元素/可迭代对象的某个属性或函数作为关键字,对其元素进行比较排序。默认值为None。
另外,通过指定关键字,可以使其运行效率更快。
#属性
>>> sorted("This is a test string from Andrew".split(), key=str.lower)
['a', 'Andrew', 'from', 'is', 'string', 'test', 'This']
#函数
>>> student_tuples = [
... ('john', 'A', 15),
... ('jane', 'B', 12),
... ('dave', 'B', 10),]
# sort by age
>>> sorted(student_tuples, key=lambda student: student[2])
[('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]
同样,也适用于具有命名属性的对象
>>> 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)]
Operator 模块函数
Operator 模块: https://docs.python.org/3/library/operator.html
operator模块是python中内置的操作符函数接口,它定义了一些算术和比较内置操作的函数。
operator模块中包含了Python的各种内置操作符,诸如逻辑、比较、计算、位运算等。
operator模块是用C实现的,所以执行速度比python代码快。
key-function patterns:
operator模块也提供了指定关键字的函数,如itemgetter()
, attrgetter()
, 和methodcaller()
,从而使accessor functions的效率更快更简单。
>>> 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)]
operator 模块的函数允许多个水平上进行排序操作
#可指定多个索引值
>>> 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)]
getitem
operator.getitem(a, b)
operator.__getitem__(a, b)
Return the value of a at index b.
>>> operator.getitem([10,2,3,5], 1)
2
itemgetter
operator.itemgetter(*items)
Return a callable object that fetches item from its operand using the operand’s
__getitem__()
method.
如果指定多个items,则返回一个查找值的元组
- After
f = itemgetter(2)
, the callf(r)
returnsr[2]
. - After
g = itemgetter(2, 5, 3)
, the callg(r)
returns(r[2], r[5], r[3])
.
>>> itemgetter(1)('ABCDEFG')
'B'
>>> itemgetter(1,3,5)('ABCDEFG')
('B', 'D', 'F')
>>> itemgetter(slice(2,None))('ABCDEFG')
'CDEFG'
#从元组中检索特定字段
>>> inventory = [('apple', 3), ('banana', 2), ('pear', 5), ('orange', 1)]
>>> getcount = itemgetter(1)
>>> list(map(getcount, inventory))
[3, 2, 5, 1]
>>> sorted(inventory, key=getcount)
[('orange', 1), ('banana', 2), ('apple', 3), ('pear', 5)]
attrgetter
operator.attrgetter(*attrs)
Return a callable object that fetches the given attribute(s) from its operand.
从其操作数中提取属性(attr),返回可调用对象。如果请求了多个属性,则返回一个元组。而且,属性名称也可以包含点。例如:
- After
f = attrgetter('name')
, the callf(b)
returnsb.name
. - After
f = attrgetter('name', 'date')
, the callf(b)
returns(b.name, b.date)
. - After
f = attrgetter('name.first', 'name.last')
, the callf(b)
returns(b.name.first, b.name.last)
.
methodcaller
operator.methodcaller(name[, args...])
Return a callable object that calls the method name on its operand.
如果给出了附加的参数或关键字参数,它们也将被赋予该方法。
- After
f = methodcaller('name')
, the callf(b)
returnsb.name()
. - After
f = methodcaller('name', 'foo', bar=1)
, the callf(b)
returnsb.name('foo', bar=1)
.
def methodcaller(name, *args, **kwargs):
def caller(obj):
return getattr(obj, name)(*args, **kwargs)
return caller
升序&降序
list.sort()
和sorted()
都有一个reverse
参数
#降序
>>> sorted(student_tuples, key=itemgetter(2), reverse=True)
[('john', 'A', 15), ('jane', 'B', 12), ('dave', 'B', 10)]
>>> sorted(student_objects, key=attrgetter('age'), reverse=True)
[('john', 'A', 15), ('jane', 'B', 12), ('dave', 'B', 10)]
当多条记录的键值(key)相同,它们的原始顺序将被保留,即当有多条记录/元素的键值相同时,则它们的排序位置根据原始顺序进行排序。
>>> data = [('red', 1), ('blue', 1), ('red', 2), ('blue', 2)]
>>> sorted(data, key=itemgetter(0))
[('blue', 1), ('blue', 2), ('red', 1), ('red', 2)]
允许在一系列排序步骤中构建复杂的排序。
# sort on secondary key
>>> s = sorted(student_objects, key=attrgetter('age'))
# now sort on primary key, descending
>>> sorted(s, key=attrgetter('grade'), reverse=True)
[('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]
numpy.argsort
numpy.argsort(a, axis=-1, kind='quicksort', order=None)[source]
默认返回排序后的数组值从小到大的索引值。
参数:
a : 待排序的array/array_like
axis : 可选项,指定沿着哪个轴进行排序,int or None。默认值 -1,即 the last axis;如果是None,则array将被扁平化,即将array转换成vector。
kind : 可选项,排序算法:‘quicksort’, ‘mergesort’, ‘heapsort’
order : 可选项,根据指定的关键字进行排序
#一维数组:
>>> x = np.array([3, 1, 2])
>>> index_array = np.argsort(x)
>>> index_array #返回排序后的数组值从小到大的索引值
array([1, 2, 0])
>>> x[index_array] #根据索引获得排序后的数组
array([1, 2, 3])
#二维数组:
>>> x = np.array([[0, 5, 3], [2, 2, 6],[1, 12, 1]])
>>> x
array([[ 0, 5, 3],
[ 2, 2, 6],
[ 1, 12, 1]])
>>> np.argsort(x, axis=0) #按列排序
array([[0, 1, 2],
[2, 0, 0],
[1, 2, 1]])
>>> np.argsort(x, axis=1) #按行排序
array([[0, 2, 1],
[0, 1, 2],
[0, 2, 1]])
#根据关键字(key)排序
>>> x = np.array([(1, 0), (0, 1)], dtype=[('x', '<i4'), ('y', '<i4')])
>>> x
array([(1, 0), (0, 1)],
dtype=[('x', '<i4'), ('y', '<i4')])
>>> np.argsort(x, order=('x','y'))
array([1, 0])
>>> np.argsort(x, order=('y','x'))
array([0, 1])
参考链接1:https://docs.python.org/3/howto/sorting.html
参考链接2:https://docs.python.org/3/library/operator.html
参考链接3:numpy.argsort