深入理解python中的排序sort

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了深入理解python中的排序sort相关的知识,希望对你有一定的参考价值。

参考技术A

进行一个简单的升序排列直接调用sorted()函数,函数将会返回一个排序后的列表:

sorted函数不会改变原有的list,而是返回一个新的排好序的list

如果你想使用就地排序,也就是改变原list的内容,那么可以使用list.sort()的方法,这个方法的返回值是None。

另一个区别是,list.sort()方法只是list也就是列表类型的方法,只可以在列表类型上调用。而sorted方法则是可以接受任何可迭代对象。

list.sort()和sorted()函数都有一个key参数,可以用来指定一个函数来确定排序的一个优先级。比如,这个例子就是根据大小写的优先级进行排序:

key参数的值应该是一个函数,这个函数接受一个参数然后返回以一个key,这个key就被用作进行排序。这个方法很高效,因为对于每一个输入的记录只需要调用一次key函数。
一个常用的场景就是当我们需要对一个复杂对象的某些属性进行排序时:

再如:

前面我们看到的利用key-function来自定义排序,同时Python也可以通过operator库来自定义排序,而且通常这种方法更好理解并且效率更高。
operator库提供了 itemgetter(), attrgetter(), and a methodcaller()三个函数

同时还支持多层排序

list.sort()和sorted()都有一个boolean类型的reverse参数,可以用来指定升序和降序排列,默认为false,也就是升序排序,如果需要降序排列,则需将reverse参数指定为true。

排序的稳定性指,有相同key值的多个记录进行排序之后,原始的前后关系保持不变

我们可以看到python中的排序是稳定的。

我们可以利用这个稳定的特性来进行一些复杂的排序步骤,比如,我们将学生的数据先按成绩降序然后年龄升序。当排序是稳定的时候,我们可以先将年龄升序,再将成绩降序会得到相同的结果。

传统的DSU(Decorate-Sort-Undecorate)的排序方法主要有三个步骤:

因为元组是按字典序比较的,比较完grade之后,会继续比较i。
添加index的i值不是必须的,但是添加i值有以下好处:

现在python3提供了key-function,所以DSU方法已经不常用了

python2.x版本中,是利用cmp参数自定义排序。
python3.x已经将这个方法移除了,但是我们还是有必要了解一下cmp参数
cmp参数的使用方法就是指定一个函数,自定义排序的规则,和java等其他语言很类似

也可以反序排列

python3.x中可以用如下方式:

深入理解Arrays.sort() (转)

Arrays.sort(T[], Comparator < ? super T > c) 方法用于对象数组按用户自定义规则排序.
官方Java文档只是简要描述此方法的作用,并未进行详细的介绍,本文将深入解析此方法。
1. 简单示例
sort方法的使用非常的简单明了,下面的例子中,先定义一个比较Dog大小的Comparator,然后将其实例对象作为参数传给sort方法,通过此示例,你应该能够快速掌握Arrays.sort()的使用方法。

[java] view plaincopy
 
 
  1. import java.util.Arrays;  
  2. import java.util.Comparator;  
  3.    
  4. class Dog{  
  5.     int size;     
  6.     public Dog(int s){  
  7.         size = s;  
  8.     }  
  9. }  
  10.    
  11. class DogSizeComparator implements Comparator<Dog>{  
  12.    
  13.     @Override  
  14.     public int compare(Dog o1, Dog o2) {  
  15.         return o1.size - o2.size;  
  16.     }  
  17. }  
  18.    
  19. public class ArraySort {  
  20.    
  21.     public static void main(String[] args) {  
  22.         Dog d1 = new Dog(2);  
  23.         Dog d2 = new Dog(1);  
  24.         Dog d3 = new Dog(3);  
  25.    
  26.         Dog[] dogArray = {d1, d2, d3};  
  27.         printDogs(dogArray);  
  28.    
  29.         Arrays.sort(dogArray, new DogSizeComparator());   
  30.         printDogs(dogArray);  
  31.     }  
  32.    
  33.     public static void printDogs(Dog[] dogs){  
  34.         for(Dog d: dogs)  
  35.             System.out.print(d.size + " " );  
  36.    
  37.         System.out.println();  
  38.     }  
  39. }  

输出为:

[plain] view plaincopy
 
 
  1. 2 1 3  
  2. 1 2 3  


2. 使用策略模式
这是策略模式(Strategy pattern)的一个完美又简洁的示例,值得一提的是为什么这种场景下适合使用策略模式.
总体来说,策略模式允许在程序执行时选择不同的算法.比如在排序时,传入不同的比较器(Comparator),就采用不同的算法.
根据上面的例子,假设你想要根据Dog的重量来进行排序,可以像下面这样,创建一个新的比较器来进行排序:

[java] view plaincopy
 
 
  1. class Dog{  
  2.     int size;  
  3.     int weight;  
  4.    
  5.     public Dog(int s, int w){  
  6.         size = s;  
  7.         weight = w;   
  8.     }  
  9. }  
  10.    
  11. class DogSizeComparator implements Comparator<Dog>{  
  12.    
  13.     @Override  
  14.     public int compare(Dog o1, Dog o2) {  
  15.         return o1.size - o2.size;  
  16.     }  
  17. }  
  18.    
  19. class DogWeightComparator implements Comparator<Dog>{  
  20.    
  21.     @Override  
  22.     public int compare(Dog o1, Dog o2) {  
  23.         return o1.weight - o2.weight;  
  24.     }  
  25. }  
  26.    
  27. public class ArraySort {  
  28.    
  29.     public static void main(String[] args) {  
  30.         Dog d1 = new Dog(2, 50);  
  31.         Dog d2 = new Dog(1, 30);  
  32.         Dog d3 = new Dog(3, 40);  
  33.    
  34.         Dog[] dogArray = {d1, d2, d3};  
  35.         printDogs(dogArray);  
  36.    
  37.         Arrays.sort(dogArray, new DogSizeComparator());   
  38.         printDogs(dogArray);  
  39.    
  40.         Arrays.sort(dogArray, new DogWeightComparator());     
  41.         printDogs(dogArray);  
  42.     }  
  43.    
  44.     public static void printDogs(Dog[] dogs){  
  45.         for(Dog d: dogs)  
  46.             System.out.print("size="+d.size + " weight=" + d.weight + " ");  
  47.    
  48.         System.out.println();  
  49.     }  
  50. }  

执行结果:

[plain] view plaincopy
 
 
  1. size=2 weight=50 size=1 weight=30 size=3 weight=40  
  2. size=1 weight=30 size=2 weight=50 size=3 weight=40  
  3. size=1 weight=30 size=3 weight=40 size=2 weight=50  

Comparator 是一个接口,所以sort方法中可以传入任意实现了此接口的类的实例,这就是策略模式的主要思想.

3. 为何使用"super"
如果使用 "Comparator < T > c" 那是很简单易懂的,但是sort的第2个参数里面的 < ? super T > 意味着比较器所接受的类型可以是T或者它的超类. 为什么是超类呢? 答案是: 这允许使用同一个比较器对不同的子类对象进行比较.在下面的示例中很明显地演示了这一点:

[java] view plaincopy
 
 
  1. import java.util.Arrays;  
  2. import java.util.Comparator;  
  3.    
  4. class Animal{  
  5.     int size;  
  6. }  
  7.    
  8. class Dog extends Animal{  
  9.     public Dog(int s){  
  10.         size = s;  
  11.     }  
  12. }  
  13.    
  14. class Cat extends Animal{  
  15.     public Cat(int s){  
  16.         size  = s;  
  17.     }  
  18. }  
  19.    
  20. class AnimalSizeComparator implements Comparator<Animal>{  
  21.    
  22.     @Override  
  23.     public int compare(Animal o1, Animal o2) {  
  24.         return o1.size - o2.size;  
  25.     }  
  26.     //in this way, all sub classes of Animal can use this comparator.  
  27. }  
  28.    
  29. public class ArraySort {  
  30.    
  31.     public static void main(String[] args) {  
  32.         Dog d1 = new Dog(2);  
  33.         Dog d2 = new Dog(1);  
  34.         Dog d3 = new Dog(3);  
  35.    
  36.         Dog[] dogArray = {d1, d2, d3};  
  37.         printDogs(dogArray);  
  38.    
  39.         Arrays.sort(dogArray, new AnimalSizeComparator());    
  40.         printDogs(dogArray);  
  41.    
  42.         System.out.println();  
  43.    
  44.         //when you have an array of Cat, same Comparator can be used.   
  45.         Cat c1 = new Cat(2);  
  46.         Cat c2 = new Cat(1);  
  47.         Cat c3 = new Cat(3);  
  48.    
  49.         Cat[] catArray = {c1, c2, c3};  
  50.         printDogs(catArray);  
  51.    
  52.         Arrays.sort(catArray, new AnimalSizeComparator());    
  53.         printDogs(catArray);  
  54.     }  
  55.    
  56.     public static void printDogs(Animal[] animals){  
  57.         for(Animal a: animals)  
  58.             System.out.print("size="+a.size + " ");  
  59.    
  60.         System.out.println();  
  61.     }  
  62. }  

输出结果:

[plain] view plaincopy
 
 
  1. size=2 size=1 size=3  
  2. size=1 size=2 size=3  
  3. size=2 size=1 size=3  
  4. size=1 size=2 size=3  


4. 小结
与Arrays.sort()相关的信息总结如下:

    1. 通用: super 类
    2. 策略设计模式(strategy pattern);
    3. 归并排序(merge sort): 时间复杂度 n*log(n);
    4. Java.util.Collections#sort(List < T > list, Comparator < ? super T > c)与Arrays.sort 使用类似的思想.


http://blog.csdn.net/wisgood/article/details/16541013

以上是关于深入理解python中的排序sort的主要内容,如果未能解决你的问题,请参考以下文章

深入理解快速排序和 STL 的 sort 算法

深入理解Arrays.sort() (转)

sort和sorted深入理解----引子:多维列表,如何实现第一个元素升序,第二个元素降序

冒泡排序深入理解

Python | 深入希尔排序世界

深入理解Pandas数据排序