2015-04-19 20 views
5

Zaczynam od nauki Pythona 3. Zastanawiam się, jak wykonać sortowanie niestandardowe. Na przykład, mogę chcieć posortować listę zwierząt w następujący sposób: sortuj według pierwszego znaku rosnąco, następnie według długości malejąco, następnie alfanumerycznie rosnąco.Niestandardowe sortowanie w Pythonie 3

Lista złożona z "mrówki", "antylopy", "zebry", "mrówkojada" po prawidłowym posortowaniu stanie się "mrówkojadem", "antylopą", "mrówką", "zebrą".

Przeczytałem trochę na dokumentach, ale nie całkiem dostałem argument "klucz" do metody sortowania. Dowolne przykłady? PS: to nie jest pytanie o przydzielenie uczelni. Po prostu chcę trochę pogadać z pytonem.

Dowiedziałem Java dawno, dawno temu, a może wdrożyły coś zwyczaj sortowania jak następuje:

import java.util.*; 

public class sortDemo implements Comparator<String> { 
    public static void main(String[] args) { 
     ArrayList<String> animals = new ArrayList<String>(); 
     animals.add("ant"); 
     animals.add("antelope"); 
     animals.add("zebra"); 
     animals.add("anteater"); 

     for (String a:animals){ 
      System.out.println(a); 
     } 
     System.out.println(); 

     // want output to be anteater, antelope, ant, zebra following the sort 
     Collections.sort(animals, new sortDemo()); 

     for (String a:animals){ 
      System.out.println(a); 
     } 
    } 

    public int compare(String s1, String s2) { 
     if (s1.charAt(0) > s2.charAt(0)){ 
      return 1; 
     } else if (s1.charAt(0) == s2.charAt(0)){ 
      if(s1.length() < s2.length()) { 
       return 1; 
      } else if (s1.length() == s2.length()) { 
       return s1.compareTo(s2); 
      } else { 
       return -1; 
      } 
     } else { 
      return -1; 
     } 
    } 
} 
+0

[docs] (https://docs.python.org/3/howto/sorting.html) są dość proste. Wygląda na to, że twoje porównanie jest złożone, co oznacza, że ​​'cmp_to_key' może być tym, czego szukasz (przeszukaj dokumenty). – alfasin

Odpowiedz

7

Klucz sortowania jest funkcją, która, biorąc pod uwagę element listy, zwraca wartość że Python wie, jak porównać natywnie. Na przykład Python wie, jak porównać liczby całkowite i łańcuchy.

Python może również porównywać krotki i listy, które składają się z elementów, które można porównać. Sposób porównania krotek i list polega na tym, że wcześniejsze elementy krotki lub listy mają pierwszeństwo przed późniejszymi wartościami, tak jak można się spodziewać.

W twoim przypadku, co chcesz zrobić następującą funkcję klucza:

lambda name: (name[0], -len(name), name) 

przedmioty z mniejszych kluczy zawsze przyjść wcześniej w posortowanej listy. Tak więc mniejszy początkowy charakter powoduje, że zwierzę przychodzi wcześniej. Jeśli dwie nazwy mają ten sam inicjał, dłuższa długość nazwy powoduje, że zwierzę przychodzi wcześniej, ponieważ długość ujemnej nazwy jest mniejsza. Wreszcie, jeśli nazwy dwóch zwierząt mają tę samą początkową i taką samą długość, remis jest łamany przez kolejność leksykograficzną.

Ten program pokazuje, jak posortować listę z funkcją przycisku powyżej:

animals = ["ant", "antelope", "zebra", "anteater", "cod", "cat"] 

animals.sort(key=lambda name: (name[0], -len(name), name)) 

print(animals) 
+1

Nice! Nigdy nie myślałem o używaniu listy do tego celu, to naprawdę ułatwia sprawę! Przy okazji, nie musisz zwracać listy, tuple zrobi również tę samą sztuczkę! – alfasin

+1

Masz całkowitą rację. Krotka jest koncepcyjnie lepsza jako klucz sortujący, ponieważ jest niezmienna. Odpowiednio zredagowałem swoją odpowiedź. –

0

Docs Pythona dać excellent examples for .sort and sorted()

Powiedział:

animals = ["Anteater", "Aardvark", "Eagle", "Platypus"] 
sorted(animals, key=lambda animal: animal[2]) 
['Platypus', 'Eagle', 'Aardvark', 'Anteater'] 

Kluczem tutaj jest trzeci litera każdego imienia zwierzęcia. Zrobiłem trzecią literę kluczem przy użyciu funkcji lambda lambda: animal: animal[2]. Ta funkcja lambda pozwoliła mi określić trzecią literę, ponieważ nie mogłem po prostu powiedzieć key=animal[2], ponieważ zwierzę byłoby niezdefiniowane.

Powiązane problemy