python中sort()、sorted()函数比较

遇到一道题,说是列表L=[1,6,5,3,9,12,13,33],对L进行判断,如果L是升序排列的,那么输出’UP’;如果L是降序排序的,输出’DOWN’;如果上述两者都不是,那么输出’WRONG’。

当然这个问题也不难,但是我当时采取的方法比较繁琐,先将L神拷贝给L1,然后对L1排序,再将L和L1比较。

另外一种比较简洁的方法一句话就能完成,利用了sorted()函数,如下:

print ‘UP’ if L==sorted(L) else ‘DOWN’ if L==sorted(L)[::-1] else ‘WRONG’

是不是很简洁、一目了然?所以熟悉python中众多的小函数,可以帮助我们快速编程并且很简洁。

1).sorted(L)函数和L.sort()函数

sorted(iterable[,cmp,[,key[,reverse=True]]])

作用:第一个参数是一个iterable,返回值是一个对iterable中元素进行排序后的列表(list)。

可选的参数有三个,cmp、key和reverse。

>>> L=[1,6,5,3,9,12,13,33]

>>> sorted(L)
    [1, 3, 5, 6, 9, 12, 13, 33]
    >>> L
    [1, 6, 5, 3, 9, 12, 13, 33]
    可见sorted()函数并不改变原来L的顺序,只是返回一个新的列表,这个列表是按照升序排列的。

sort()函数就不一样了,它会改变原来L的顺序。

>>> L.sort()

>>> L
    [1, 6, 5, 3, 9, 12, 13, 33]

通常这个方法不如sorted(L)方便,但是List.sort()这个方法的效率要高一点。

另一个区别在于list.sort()方法只为list定义。而sorted()函数可以接收任何的iterable。

2).函数新特性(key-function模式)

从Python2.4开始,list.sort()和sorted()方法都添加了一个key参数来说明一个函数,这个函数在做比较之前会对list中的每个元素进行调用。

例如,这里是一个大小写不敏感的字符串比较:

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

['a', 'Andrew', 'from', 'is', 'string', 'test', 'This']

key的值应该是一个函数,这个函数接收一个参数并且返回一个用于比较的关键字。这种技术比较快,原因在于对每个输入记录,这个函数只会被调用一次。

对复杂对象的比较通常是使用对象的切片作为关键字。例如:

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

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

>>> sorted(student_tuples, key=lambda student: student[2])  

# sort by age [('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]

同样的技术适用于有named属性的对象。例如:

>>> 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)]

3)Operator Module Functions (Operator模块中的函数)

上面的key-function模式很常见,因此Python提供了方便的函数使得祖先函数更简单和快捷。operator module有itemgetter,attrgetter,以及从Python2.6开始的methodcaller函数。

使用这些函数,上面的例子会变得更简单和快捷:

>>> 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)]

 

4).升序和降序

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)]

5).排序稳定性和复杂的排序

从Python2.2开始,排序都保证是稳定的。意思是当多个记录有相同的关键字时,它们原始的排序保留。

>>> data = [('red', 1), ('blue', 1), ('red', 2), ('blue', 2)]

>>> sorted(data, key=itemgetter(0))

[('blue', 1), ('blue', 2), ('red', 1), ('red', 2)]

注意到两个'blue'的记录保留了它们原始的顺序,因此('blue',1)保证在('blue',2)之前。 

这个好的特性能让你建立复杂的排序。

例如,将学生记录按成绩降序排序、按年两升序排列。先按年龄排序,再按成绩排序。

>>> s=sorted(student_object,key=attrgettter('age'))

# sort on secondary key

>>> sorted(s,key=attrgetter('grade'),reverse=True)

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

 

附上一张秦时明月里面的图:

python中sort()、sorted()函数比较_第1张图片

 

你可能感兴趣的:(python中sort()、sorted()函数比较)