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 call f(r) returns r[2].
  • After g = itemgetter(2, 5, 3), the call g(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 call f(b) returns b.name.
  • After f = attrgetter('name', 'date'), the call f(b) returns (b.name, b.date).
  • After f = attrgetter('name.first', 'name.last'), the call f(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 call f(b) returns b.name().
  • After f = methodcaller('name', 'foo', bar=1), the call f(b) returns b.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

posted @ 2017-11-01 15:04  AdaWongCorner  阅读(384)  评论(0编辑  收藏  举报