Python Sort List Array Method - Stigende og faldende forklaret med eksempler

Hvis du vil lære at arbejde med sort()metoden i dine Python-projekter, er denne artikel noget for dig. Denne metode er meget kraftfuld, og du kan tilpasse den til dine behov, så lad os se, hvordan den fungerer i detaljer.

Du vil lære:

  • Sådan bruges denne metode og tilpasser dens funktionalitet.
  • Hvornår skal du bruge det, og hvornår det ikke skal bruges.
  • Hvordan man kalder det passerer forskellige kombinationer af argumenter.
  • Sådan sorteres en liste i stigende og faldende rækkefølge.
  • Sådan sammenlignes elementerne på en liste baseret på mellemværdier.
  • Hvordan du kan overføre lambdafunktioner til denne metode.
  • Hvordan denne metode kan sammenlignes med sorted()funktionen.
  • Hvorfor sort()metoden udfører en stabil sortering.
  • Hvordan mutationsprocessen fungerer bag kulisserne.

Er du klar? Lad os begynde! ⭐

? Formål og brugssager

Med sort()metoden kan du sortere en liste i enten:

  • Stigende rækkefølge
  • Faldende rækkefølge

Denne metode bruges til at sortere en liste på plads, hvilket betyder at den muterer den eller ændrer den direkte uden at oprette yderligere kopier, så husk:

Du vil lære mere om mutation i denne artikel (jeg lover!), Men for nu er det meget vigtigt, at du ved, at sort()metoden ændrer listen, så dens originale version går tabt.

På grund af dette bør du kun bruge denne metode, hvis:

  • Du vil ændre (sortere) listen permanent.
  • Du behøver ikke at beholde den oprindelige version af listen.

Hvis dette passer til dine behov, er .sort()metoden nøjagtigt det, du leder efter.

? Syntaks og argumenter

Lad os se, hvordan du kan ringe for .sort()at drage fordel af dens fulde kraft.

Dette er det mest basale opkald (uden argumenter):

Hvis du ikke sender nogen argumenter, som standard:

  • Listen sorteres i stigende rækkefølge.
  • Elementerne på listen sammenlignes direkte ved hjælp af deres værdier med <operatøren.

For eksempel:

>>> b = [6, 3, 8, 2, 7, 3, 9] >>> b.sort() >>> b [2, 3, 3, 6, 7, 8, 9] # Sorted!

Brugerdefinerede argumenter  

For at tilpasse, hvordan sort()metoden fungerer, kan du videregive to valgfri argumenter:

  • Nøgle
  • Baglæns

Lad os se, hvordan de ændrer opførelsen af ​​denne metode. Her har vi et metodekald med disse to argumenter:

Inden jeg forklarer, hvordan de fungerer, vil jeg gerne forklare noget, som du sandsynligvis har bemærket i diagrammet ovenfor - i metodekaldet skal navnene på parametrene medtages før deres tilsvarende værdier, som denne:

  • key=
  • reverse=

Dette er fordi de kun er søgeordsargumenter . Hvis du sender en brugerdefineret værdi til dem, skal deres navne angives i metodekaldet efterfulgt af et lighedstegn =og deres tilsvarende værdier som denne:

Ellers, hvis du forsøger at videregive argumenterne direkte, som vi normalt gør for positionsparametre, vil du se denne fejl, fordi funktionen ikke ved, hvilket argument svarer til hvilken parameter:

TypeError: sort() takes no positional arguments

Baglæns

Nu hvor du ved, hvad kun søgeordsargumenter er, lad os starte med reverse.

Værdien af reversekan være enten Trueeller False:

  • False betyder, at listen vil blive sorteret i stigende rækkefølge.
  • True betyder, at listen vil blive sorteret i faldende (omvendt) rækkefølge.

Tip: Som standard er dens værdi False- hvis du ikke sender nogen argumenter for denne parameter, sorteres listen i stigende rækkefølge.

Her har vi et par eksempler:

# List of Integers >>> b = [6, 3, 8, 2, 7, 3, 9] >>> b.sort() >>> b [2, 3, 3, 6, 7, 8, 9] # List of Strings >>> c = ["A", "Z", "D", "T", "U"] >>> c.sort() >>> c ['A', 'D', 'T', 'U', 'Z'] 

? Tip: Hvis elementerne på listen er strenge, sorteres de alfabetisk.

# List of Integers >>> b = [6, 3, 8, 2, 7, 3, 9] >>> b.sort(reverse=True) >>> b [9, 8, 7, 6, 3, 3, 2] # List of Strings >>> c = ["A", "Z", "D", "T", "U"] >>> c.sort(reverse=True) >>> c ['Z', 'U', 'T', 'D', 'A']

? Tip: Bemærk, hvordan listen sorteres i faldende rækkefølge, hvis den reverseer True.

Nøgle

Nu hvor du ved, hvordan du arbejder med reverseparameteren, skal vi se keyparameteren.

Denne parameter er lidt mere detaljeret, fordi den bestemmer, hvordan elementerne på listen sammenlignes under sorteringsprocessen.

Værdien af keyer enten:

  • None, hvilket betyder, at elementerne på listen sammenlignes direkte. F.eks. Kan en heltal i en liste over heltal bruges til sammenligningen.
  • En funktion af et argument, der genererer en mellemværdi for hvert element. Denne mellemværdi beregnes kun en gang, og den bruges til at foretage sammenligningerne under hele sorteringsprocessen. Vi bruger dette, når vi ikke ønsker at sammenligne elementerne direkte, for eksempel når vi vil sammenligne strenge baseret på deres længde (den mellemliggende værdi).

? Tip: Som standard er værdien af keyer None, så elementerne sammenlignes direkte.

For eksempel:

Lad os sige, at vi vil sortere en liste over strenge baseret på deres længde, fra den korteste streng til den længste streng. Vi kan passere funktionen lensom værdien af key, som denne:

>>> d = ["aaa", "bb", "c"] >>> d.sort(key=len) >>> d ['c', 'bb', 'aaa']

? Tip: Bemærk, at vi kun sender navnet på funktionen ( len) uden parentes, fordi vi ikke kalder funktionen. Dette er meget vigtigt.

Bemærk forskellen mellem at sammenligne elementerne direkte og sammenligne deres længde (se nedenfor). Brug af standardværdien af key( None) ville have sorteret strengene alfabetisk (venstre), men nu sorterer vi dem ud fra deres længde (højre):

Hvad sker der bag kulisserne? Hvert element sendes som et argument til len()funktionen, og den værdi, der returneres af dette funktionsopkald, bruges til at udføre sammenligningerne under sorteringsprocessen:

Dette resulterer i en liste med forskellige sorteringskriterier: længde.

Her har vi et andet eksempel:

Et andet interessant eksempel er at sortere en liste over strenge, som om de alle var skrevet med små bogstaver (for eksempel at gøre "Aa" svarende til "aa").

I henhold til leksikografisk rækkefølge kommer store bogstaver før små bogstaver:

>>> "E" < "e" True

Så strengen "Emma"ville komme før "emily"i en sorteret liste, selvom deres små versioner ville være i den modsatte rækkefølge:

>>> "Emma" >> "emma" < "emily" False

For at undgå at skelne mellem store og små bogstaver kan vi videregive funktionen str.lowersom key. Dette genererer en lille version af strengene, der vil blive brugt til sammenligningerne:

>>> e = ["Emma", "emily", "Amy", "Jason"] >>> e.sort(key=str.lower) >>> e ['Amy', 'emily', 'Emma', 'Jason']

Bemærk, at nu "emily"kommer før "Emma"i den sorterede liste, hvilket er præcis, hvad vi ønskede.

? Tip: hvis vi havde brugt standard sortering proces, alle de strenge, der begyndte med et stort bogstav ville være kommet før alle strengene, der startede med et lille bogstav:

>>> e = ["Emma", "emily", "Amy", "Jason"] >>> e.sort() >>> e ['Amy', 'Emma', 'Jason', 'emily']

Her er et eksempel ved hjælp af objektorienteret programmering (OOP):

Hvis vi har denne meget enkle Python-klasse:

>>> class Client: def __init__(self, age): self.age = age

Og vi opretter fire forekomster:

>>> client1 = Client(67) >>> client2 = Client(23) >>> client3 = Client(13) >>> client4 = Client(35)

Vi kan lave en liste, der refererer til dem:

>>> clients = [client1, client2, client3, client4]

Derefter, hvis vi definerer en funktion til at få de ageaf disse forekomster:

>>> def get_age(client): return client.age

Vi kan sortere listen ud fra deres alder ved at videregive get_agefunktionen til et argument:

>>> clients.sort(key=get_age)

Dette er den endelige, sorterede version af listen. Vi bruger en for-løkke til at udskrive forekomstenes alder i den rækkefølge, de vises på listen:

>>> for client in clients: print(client.age) 13 23 35 67

Præcis hvad vi ønskede - nu er listen sorteret i stigende rækkefølge baseret på instansernes alder.

? Tip: I stedet for at definere en get_agefunktion, kunne vi have brugt en lambda-funktion til at få alderen for hver forekomst, som denne:

>>> clients.sort(key=lambda x: x.age)

Lambda-funktioner er små og enkle anonyme funktioner, hvilket betyder, at de ikke har noget navn. De er meget nyttige i disse scenarier, når vi kun vil bruge dem bestemte steder i en meget kort periode.

Dette er den grundlæggende struktur for lambda-funktionen, som vi bruger til at sortere listen:

Videregivelse af begge argumenter

Fantastisk! Nu ved du at tilpasse sort()metodens funktionalitet. Men du kan tage dine færdigheder til et helt nyt niveau ved at kombinere effekten af keyog reversei samme metodeopkald:

>>> f = ["A", "a", "B", "b", "C", "c"] >>> f.sort(key=str.lower, reverse=True) >>> f ['C', 'c', 'B', 'b', 'A', 'a']

Dette er de forskellige kombinationer af argumenterne og deres virkning:

Rækkefølgen af ​​argumenter, der kun er søgeord, betyder ikke noget

Da vi specificerer navnene på argumenterne, ved vi allerede, hvilken værdi der svarer til hvilken parameter, så vi kan inkludere den ene keyeller den reverseførste på listen, og effekten vil være nøjagtig den samme.

Så denne metode kalder:

Svarer til:

Dette er et eksempel:

>>> a = ["Zz", "c", "y", "o", "F"] >>> a.sort(key=str.lower, reverse=True) >>> a ['Zz', 'y', 'o', 'F', 'c']

Hvis vi ændrer rækkefølgen af ​​argumenterne, får vi nøjagtigt det samme resultat:

>>> a = ["Zz", "c", "y", "o", "F"] >>> a.sort(reverse=True, key=str.lower) >>> a ['Zz', 'y', 'o', 'F', 'c']

? Returneringsværdi

Lad os nu tale lidt om returværdien af ​​denne metode. De sort()metode returnerer None- det gør ikke returnere en ordnet version af listen, ligesom vi måske intuitivt forvente.

Ifølge Python-dokumentationen:

For at minde brugerne om, at den fungerer ved bivirkning, returnerer den ikke den sorterede sekvens.

Dybest set bruges dette til at minde os om, at vi ændrer den oprindelige liste i hukommelsen og ikke genererer en ny kopi af listen.

Dette er et eksempel på returværdien af sort():

>>> nums = [6.5, 2.4, 7.3, 3.5, 2.6, 7.4] # Assign the return value to this variable: >>> val = nums.sort() # Check the return value: >>> print(val) None

Se? Noneblev returneret ved metodeopkaldet.

? Tip: It is very important not to confuse the sort() method with the sorted() function, which is a function that works very similarly, but doesn't modify the original list. Instead sorted() generates and returns a new copy of the list, already sorted.

This is an example that we can use to compare them:

# The sort() method returns None >>> nums = [6.5, 2.4, 7.3, 3.5, 2.6, 7.4] >>> val = nums.sort() >>> print(val) None
# sorted() returns a new sorted copy of the original list >>> nums = [6.5, 2.4, 7.3, 3.5, 2.6, 7.4] >>> val = sorted(nums) >>> val [2.4, 2.6, 3.5, 6.5, 7.3, 7.4] # But it doesn't modify the original list >>> nums [6.5, 2.4, 7.3, 3.5, 2.6, 7.4]

This is very important because their effect is very different. Using the sort() method when you intended to use sorted() can introduce serious bugs into your program because you might not realize that the list is being mutated.

? The sort() Method Performs a Stable Sort

Now let's talk a little bit about the characteristics of the sorting algorithm used by sort().

Denne metode udfører en stabil sortering, fordi den fungerer med en implementering af TimSort, en meget effektiv og stabil sorteringsalgoritme.

Ifølge Python-dokumentationen:

En sortering er stabil, hvis den garanterer ikke at ændre den relative rækkefølge af elementer, der sammenligner ens - dette er nyttigt til sortering i flere passeringer (for eksempel sorter efter afdeling og derefter efter lønklasse).

Dette betyder, at hvis to elementer har samme værdi eller mellemværdi (nøgle), er de garanteret at forblive i samme rækkefølge i forhold til hinanden.

Lad os se, hvad jeg mener med dette. Se dette eksempel et øjeblik:

>>> d = ["BB", "AA", "CC", "A", "B", "AAA", "BBB"] >>> d.sort(key=len) >>> d ['A', 'B', 'BB', 'AA', 'CC', 'AAA', 'BBB']

Vi sammenligner elementerne baseret på deres længde, fordi vi passerede lenfunktionen som argumentet for key.

We can see that there are three elements with length 2: "BB", "AA", and "CC" in that order.

Now, notice that these three elements are in the same relative order in the final sorted list:

This is because the algorithm is guaranteed to be stable and the three of them had the same intermediate value (key) during the sorting process (their length was 2, so their key was 2).

? Tip: The same happened with "A" and "B" (length 1) and "AAA" and "BBB" (length 3), their original order relative to each other was preserved.

Now you know how the sort() method works, so let's dive into mutation and how it can affect your program.

? Mutation and Risks

As promised, let's see how the process of mutation works behind the scenes:

When you define a list in Python, like this:

a = [1, 2, 3, 4]

You create an object at a specific memory location. This location is called the "memory address" of the object, represented by a unique integer called an id.

You can think of an id as a "tag" used to identify a specific place in memory:

You can access a list's id using the id() function, passing the list as argument:

>>> a = [1, 2, 3, 4] >>> id(a) 60501512

When you mutate the list, you change it directly in memory. You may ask, why is this so risky?

It's risky because it affects every single line of code that uses the list after the mutation, so you may be writing code to work with a list that is completely different from the actual list that exists in memory after the mutation.

This is why you need to be very careful with methods that cause mutation.

In particular, the sort() method mutates the list. This is an example of its effect:

Here is an example:

# Define a list >>> a = [7, 3, 5, 1] # Check its id >>> id(a) 67091624 # Sort the list using .sort() >>> a.sort() # Check its id (it's the same, so the list is the same object in memory) >>> id(a) 67091624 # Now the list is sorted. It has been mutated! >>> a [1, 3, 5, 7]

The list was mutated after calling .sort().

Every single line of code that works with list a after the mutation has occurred will use the new, sorted version of the list. If this was not what you intended, you may not realize that other parts of your program are working with the new version of the list.

Here is another example of the risks of mutation within a function:

# List >>> a = [7, 3, 5, 1] # Function that prints the elements of the list in ascending order. >>> def print_sorted(x): x.sort() for elem in x: print(elem) # Call the function passing 'a' as argument >>> print_sorted(a) 1 3 5 7 # Oops! The original list was mutated. >>> a [1, 3, 5, 7]

The list a that was passed as argument was mutated, even if that wasn't what you intended when you initially wrote the function.

? Tip: If a function mutates an argument, it should be clearly stated to avoid introducing bugs into other parts of your program.

? Summary of the sort() Method

  • The sort() method lets you sort a list in ascending or descending order.
  • It takes two keyword-only arguments: key and reverse.
  • reverse determines if the list is sorted in ascending or descending order.
  • key is a function that generates an intermediate value for each element, and this value is used to do the comparisons during the sorting process.
  • The sort() method mutates the list, causing permanent changes. You need to be very careful and only use it if you do not need the original version of the list.

Jeg håber virkelig, at du kunne lide min artikel og fandt det nyttigt. Nu kan du arbejde medsort()metoden i dine Python-projekter. Tjek mine online kurser. Følg mig på Twitter. ⭐️