Sortowanie w Pythonie

Najłatwiejszym sposobem sortowania jest użycie funkcji sortowania, która pobiera listę i zwraca nową listę z tymi elementami w kolejności posortowanej. Pierwotna lista nie uległa zmianie.

  a = [5, 1, 4, 3]
  print(sorted(a))  ## [1, 3, 4, 5]
  print(a)  ## [5, 1, 4, 3]

Najczęściej przekazuje się listę do funkcji matching(), ale w rzeczywistości może ona przyjmować jako dane wejściowe dowolnego rodzaju powtarzalnego zbioru. Starsza metoda list.sort() jest alternatywną metodą opisaną poniżej. Funkcja sortowana() wydaje się łatwiejsza w użyciu niż funkcja sort(), więc zalecam korzystanie z funkcji sortowania().

Funkcję Stackdriver() można dostosować za pomocą opcjonalnych argumentów. Opcjonalny argument offset(), który zwraca wartość Prawda, np. sortowana(lista, odwrócone=Prawda), powoduje sortowanie odwrotne.

  strs = ['aa', 'BB', 'zz', 'CC']
  print(sorted(strs))  ## ['BB', 'CC', 'aa', 'zz'] (case sensitive)
  print(sorted(strs, reverse=True))   ## ['zz', 'aa', 'CC', 'BB']

Sortowanie niestandardowe (klucz=)

Aby przeprowadzić bardziej złożone sortowanie niestandardowe, metoda sortowana korzysta z opcjonalnej funkcji „key=”, która przekształca każdy element przed porównaniem. Funkcja klucza pobiera 1 wartość i zwraca 1 wartość, a zwracana wartość „proxy” jest używana do porównań w ramach sortowania.

Na przykład w przypadku listy ciągów podanie parametru key=len (wbudowana funkcja len()) sortuje ciągi według długości od najkrótszego do najdłuższego. Sortowanie wywołuje dla każdego ciągu funkcję len(), aby uzyskać listę wartości długości serwera proxy, a następnie sortuje dane według tych wartości.

  strs = ['ccc', 'aaaa', 'd', 'bb']
  print(sorted(strs, key=len))  ## ['d', 'bb', 'ccc', 'aaaa']

wywołania posortowane według parametru key=len

Innym przykładem jest określenie parametru „str.lower” jako funkcji klucza i wymuszenie sortowania w taki sam sposób, aby duże i małe litery były traktowane tak samo:

  ## "key" argument specifying str.lower function to use for sorting
  print(sorted(strs, key=str.lower))  ## ['aa', 'BB', 'CC', 'zz']

Możesz też przekazać własną funkcję MyFn jako kluczową funkcję, na przykład:

  ## Say we have a list of strings we want to sort by the last letter of the string.
  strs = ['xc', 'zb', 'yd' ,'wa']

  ## Write a little function that takes a string, and returns its last letter.
  ## This will be the key function (takes in 1 value, returns 1 value).
  def MyFn(s):
    return s[-1]

  ## Now pass key=MyFn to sorted() to sort by the last letter:
  print(sorted(strs, key=MyFn))  ## ['wa', 'zb', 'xc', 'yd']

Aby przeprowadzić bardziej złożone sortowanie, takie jak sortowanie według nazwiska, a potem według imienia, możesz użyć funkcji itemgetter lub attrgetter, takich jak:

  from operator import itemgetter

  # (first name, last name, score) tuples
  grade = [('Freddy', 'Frank', 3), ('Anil', 'Frank', 100), ('Anil', 'Wang', 24)]
  sorted(grade, key=itemgetter(1,0))
  # [('Anil', 'Frank', 100), ('Freddy', 'Frank', 3), ('Anil', 'Wang', 24)]

  sorted(grade, key=itemgetter(0,-1))
  #[('Anil', 'Wang', 24), ('Anil', 'Frank', 100), ('Freddy', 'Frank', 3)]

metoda sort()

Alternatywą dla metody sort() jest metoda sort() na liście, która sortuje tę listę w kolejności rosnącej, np. list.sort(). Metoda sort() zmienia bazową listę i zwraca wartość Brak, więc zastosuj ją w następujący sposób:

  alist.sort()            ## correct
  alist = blist.sort()    ## Incorrect. sort() returns None

Powyżej występuje bardzo częste nieporozumienie dotyczące funkcji sortowania() – *nie zwraca* posortowanej listy. Metoda sort() musi zostać wywołana z listy; nie działa dla żadnych zbiorów obliczeniowych (ale funkcja sortowana() na każdym działaniu działa). Metoda sort() jest wcześniejszą niż funkcja sortowana(), więc prawdopodobnie będziesz widzieć ją w starszym kodzie. Metoda sort() nie musi tworzyć nowej listy, więc może działać trochę szybciej, jeśli elementy do sortowania już znajdują się na liście.

Kropki

Kropka to grupa elementów o stałym rozmiarze, np. współrzędna (x i y). Kropki są jak listy, tyle że są niezmienne i nie zmieniają rozmiaru (tupki nie są stałe, bo jeden z elementów w nich może być zmienny). Kropki odgrywają w Pythonie rodzaj „struktury”, czyli wygodny sposób na przekazywanie małego, logicznego pakietu wartości o stałym rozmiarze. Funkcja, która musi zwracać wiele wartości, może po prostu zwrócić kropkę wartości. Na przykład jeśli chcesz uzyskać listę współrzędnych w 3D, naturalną reprezentacją Pythona będzie lista krotek, gdzie każda krotka ma rozmiar 3 i zawiera jedną grupę (x, y, z).

Aby utworzyć krotkę, podaj wartości w nawiasach, rozdzielając je przecinkami. „Pusta” krotka to po prostu pusta para nawiasów. Dostęp do elementów w kropce działa tak samo jak do listy – len(), [ ], for, in itp. wszystko działa tak samo.

  tuple = (1, 2, 'hi')
  print(len(tuple))  ## 3
  print(tuple[2])    ## hi
  tuple[2] = 'bye'  ## NO, tuples cannot be changed
  tuple = (1, 2, 'bye')  ## this works

Aby utworzyć krotkę o rozmiarze 1, po jednym elemencie musi być przecinek.

  tuple = ('hi',)   ## size-1 tuple

Jest to zabawny przypadek w składni, ale przecinek jest niezbędny do odróżnienia krotki od zwykłego przypadku umieszczania wyrażenia w nawiasach. W niektórych przypadkach możesz pominąć nawias, a Python w przecinku zobaczy, że chodzi o kropkę.

Przypisanie krotki do kropki z nazwami zmiennych o identycznym rozmiarze powoduje przypisanie wszystkich odpowiadających jej wartości. Jeśli krotki mają różne rozmiary, powoduje zgłoszenie błędu. Ta funkcja działa również w przypadku list.

  (x, y, z) = (42, 13, "hike")
  print(z)  ## hike
  (err_string, err_code) = Foo()  ## Foo() returns a length-2 tuple

Wyświetlanie listy definicji (opcjonalnie)

Zrozumienie list to funkcja bardziej zaawansowana, która w niektórych przypadkach się przydaje, ale nie jest potrzebna do wykonywania ćwiczeń i nie musisz jej od razu opanować (np. możesz pominąć tę sekcję). Interpretacja listy to kompaktowy sposób na zapisanie wyrażenia, które rozwija się do całej listy. Załóżmy, że mamy listę o numerach [1, 2, 3, 4]. Przedstawiona jest lista w celu obliczenia listy ich kwadratów [1, 4, 9, 16]:

  nums = [1, 2, 3, 4]

  squares = [ n * n for n in nums ]   ## [1, 4, 9, 16]

Składnia to [ expr for var in list ]for var in list wygląda jak standardowa pętla for, ale bez dwukropka (:). Parametr expr po jego lewej stronie jest sprawdzany raz dla każdego elementu w celu podania wartości nowej listy. Oto przykład z ciągami znaków, w których każdy ciąg zamieniono na wielkie litery z dodanym symbolem „!!!”:

  strs = ['hello', 'and', 'goodbye']

  shouting = [ s.upper() + '!!!' for s in strs ]
  ## ['HELLO!!!', 'AND!!!', 'GOODBYE!!!']

Aby zawęzić wynik, po prawej stronie pętli for możesz dodać test „if”. Test if jest oceniany dla każdego elementu, w tym tylko tych, dla których jest on prawdziwy.

  ## Select values <= 2
  nums = [2, 8, 1, 6]
  small = [ n for n in nums if n <= 2 ]  ## [2, 1]

  ## Select fruits containing 'a', change to upper case
  fruits = ['apple', 'cherry', 'banana', 'lemon']
  afruits = [ s.upper() for s in fruits if 'a' in s ]
  ## ['APPLE', 'BANANA']

Ćwiczenie: list1.py

Aby przećwiczyć materiał z tej sekcji, przejdź do kolejnych zadań w list1.py, w których jest używane sortowanie i krotki (w sekcji Ćwiczenia podstawowe).