Python 排序相关

Python 排序相关

当要我们要对一个list or dict 进行排序 Python提供了两种方法
方法一 使用 list.sort( ) 进行排序
方法二 使用 sorted( ) 内置函数进行
首先呢先看一下Python的排序规则

Python的 排序规则

###对于数字的排序
当这个序列里面只含有数字的时候 ,默认按照数字由大到小的顺序进行排列。
例子如下:

#对于数字的排序
li = [1,22,22,3,4]
#li.sort 会修改原来的list
li.sort()
print(li)
li2 = [1,22,22,3,4]
#sorted()会再生成一个list
new_li = sorted(li2)
print(li2)
print(new_li)

注意!!字符和数字混合的序列不能进行排序
例如:

li3 = [1,2,4,"6",5]
li3.sort()
print(li3)

报错如下:

TypeError: '<' not supported between instances of 'str' and 'int'

###Python对于字符的排序规则
比如对这个队列进行排序
li4=["1","5","3","223","1223","A","B","_","a","b","abc","张","赵","郭","谢"]

li4 =["1","5","3","223","1223","A","B","_","a","b","abc","张","赵","郭","谢"]
li4.sort()
for i in li4:
    print(bytes(i,encoding="utf-8"))
print(li4)

结果如下:
[‘1’, ‘1223’, ‘223’, ‘3’, ‘5’, ‘A’, ‘B’, ‘_’, ‘a’, ‘abc’, ‘b’, ‘张’, ‘谢’, ‘赵’, ‘郭’]
看的出,结果和我们预想的有点不太一样。
我们先将排序后的,每个字符的二进制编码输出一下。

b'1'
b'1223'
b'223'
b'3'
b'5'
b'A'
b'B'
b'_'
b'a'
b'abc'
b'b'
b'\xe5\xbc\xa0'
b'\xe8\xb0\xa2'
b'\xe8\xb5\xb5'
b'\xe9\x83\xad'
['1', '1223', '223', '3', '5', 'A', 'B', '_', 'a', 'abc', 'b', '张', '谢', '赵', '郭']

###字符型数据排序规则总结
####对于数字型字符:
先比较第一位,数字小的在前面。
接着比较第二位,数字小的也在前面。
剩下的以此类推。
####对于纯字符的字母
按照它对应的ascll码进行排序,由大到小(注意!! 不同于字符型数字,不要搞混)。
####对于中文字符等:
按照中文字符对应的16进制编码比较。由大到小,和纯字符的字母相同。

##Python 如何排序
看完了Python的排序规则,接下来介绍一下两种排序方法的使用和区别。
###基本排序

#!/usr/bim/env python3
list.sort
li = [1,22,22,3,4]
#li.sort 会修改原来的list
li.sort()
print(li)
sorted( )
li2 = [1,22,22,3,4]
#sorted()会再生成一个list
new_li = sorted(li2)
print(li2)
print(new_li)

两者的第一个不同就是list.sort()会修改原list,而sorted()会生成一个序列。
第二个不同便是list.sort() 是为list提供的方法,只能list的对象使用。而sorted可以为其他可以迭代的使用
如一个字典类型:

sorted({1: 'D', 2: 'B', 3: 'B', 4: 'E', 5: 'A'})
[1, 2, 3, 4, 5]

###key 函数
从python2.4开始,list.sort()和sorted()函数增加了key参数来指定一个函数,此函数将在每个元素比较前被调用。
例如通过key指定的函数来忽略字符串的大小写:
例子来自官网https://wiki.python.org/moin/HowTo/Sorting

#!/usr/bim/env python3
print(sorted("This is a test string from Andrew".split(), key=str.lower))
['a', 'Andrew', 'from', 'is', 'string', 'test', 'This']

对于复杂一点的也是支持,比如按照 年龄(数字)来排序

#!/usr/bin/env python3
student_tuples = [
        ('john', 'A', 15),
        ('jane', 'B', 12),
        ('dave', 'B', 10),
]
ret = sorted(student_tuples, key=lambda student: student[2])
print(ret)
#结果是
#[('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]

###sorted( )介绍
由于更加复杂的方法只在sorted( ) 函数中提供,所以下面就先介绍一想sorted的用法。
sorted(iterable[, key][, reverse]) new sorted list
iterable:是可迭代类型;
key:用列表元素的某个属性或函数进行作为关键字,有默认值,迭代集合中的一项;
reverse:排序规则. reverse = True 降序 或者 reverse = False 升序,有默认值。
返回值:是一个经过排序的可迭代类型,与iterable一样。
注意1;key可以使用lambda表达式。
注意2: 在python3.0中,cmp参数被彻底的移除了,从而简化和统一语言,减少了高级比较和cmp方法的冲突。

###Operator 模块函数
上面的key参数的使用非常广泛,因此python提供了一些方便的函数来使得访问方法更加容易和快速。operator模块有itemgetter,attrgetter,从2.6开始还增加了methodcaller方法。
使用这些方法,上面的操作将变得更加简洁和快速:

#!/usr/bim/env python3
student_tuples = [
        ('john', 'A', 15),
        ('jane', 'B', 12),
        ('dave', 'B', 10),
]

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),
        ]
#首先从operator 导入
from operator import itemgetter, attrgetter
ret = sorted(student_tuples, key=itemgetter(2))
ret2 = sorted(student_objects, key=attrgetter('age'))
print(ret)
print(ret2)
#结果如下
#[('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]
#[('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]

###升序和降序
list.sort()和sorted()都接受一个参数reverse(True or False)来表示升序或降序排序。
例如对上面的student:

#!/usr/bim/env python3
from operator import itemgetter
#降序
ret = sorted(student_tuples,key=itemgetter(2),reverse=True)
#升序
ret2 = sorted(student_tuples,key=itemgetter(2),reverse=False)
print(ret)
print(ret2)
#结果如下
#[('john', 'A', 15), ('jane', 'B', 12), ('dave', 'B', 10)]
#[('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]

##相关链接:
英文文档https://docs.python.org/3/howto/sorting.html
翻译http://www.jb51.net/article/57678.htm

发表评论

电子邮件地址不会被公开。 必填项已用*标注