• Como usar esse método e personalizar sua funcionalidade.
  • Quando usá-lo e quando não usá-lo.
  • Como chamá-lo passando diferentes combinações de argumentos.
  • Como classificar uma lista em ordem crescente e decrescente.
  • Como comparar os elementos de uma lista com base em valores intermediários.
  • Como você pode passar funções lambda para esse método.
  • Como esse método se compara ao sorted() função.
  • Porque o sort() O método executa uma classificação estável.
  • Como o processo de mutação funciona nos bastidores.

Você está pronto? Vamos começar! ⭐

Objetivo e casos de uso

Com o sort() método, você pode classificar uma lista em:

  • Ordem ascendente
  • Ordem decrescente

Particularmente, esse método é usado para classificar uma lista, o que significa que muda ou modifica-o diretamente sem criar cópias adicionais, lembre-se:

image 113

Você aprenderá mais sobre mutação neste artigo (prometo!), Mas, por enquanto, é muito importante que você saiba que o sort() O método modifica a lista, para que sua versão original seja perdida permanentemente no programa.

Por esse motivo, você só deve usar este método se:

  • Você deseja modificar (classificar) a lista permanentemente.
  • Você não precisa manter a versão original da lista.

Se isso atender às suas necessidades, o .sort() O método é exatamente o que você está procurando.

Sintaxe e argumentos

Vamos ver como você pode ligar .sort() tirar proveito de todo o seu poder.

Esta é a chamada mais básica (sem argumentos):

image 41

Se você não passar nenhum argumento, por padrão:

  • A lista será classificada em ordem crescente.
  • Os elementos da lista serão comparados diretamente usando seus valores, com o < operador.

Por exemplo:

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

Argumentos personalizados

Para personalizar como o sort() método funciona, você pode passar dois argumentos opcionais:

Vamos ver como eles mudam o comportamento desse método. Aqui temos uma chamada de método com esses dois argumentos:

image 42

Antes de explicar como eles funcionam, eu gostaria de explicar algo que você provavelmente notou no diagrama (acima): na chamada do método, os nomes dos parâmetros devem ser incluídos antes dos valores correspondentes, assim:

Isso é porque eles são argumentos apenas de palavras-chave. Se você estiver passando um valor personalizado para eles, os nomes deve ser especificado na chamada do método, seguido por um sinal de igual = e seus valores correspondentes, assim:

image 46

Caso contrário, se você tentar passar os argumentos diretamente, como fazemos normalmente para parâmetros posicionais, você verá este erro porque a função não saberá qual argumento corresponde a qual parâmetro:

TypeError: sort() takes no positional arguments

Marcha ré

Agora que você agora o que são argumentos apenas de palavras-chave, vamos começar com reverse.

O valor de reverse pode ser True ou False:

  • False significa que a lista será classificada em ordem crescente.
  • True significa que a lista será classificada em ordem decrescente (reversa).

💡 Dica: Por padrão, seu valor é False se você não passar nenhum argumento para esse parâmetro, a lista será classificada em ordem crescente.

Aqui temos alguns exemplos:

image 123
Por padrão, o reverso é Falso

# 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']

💡 Dica: Se os elementos da lista forem cadeias, eles serão classificados em ordem alfabética.

image 117
Para especificar que o reverso é True, a lista deve ser classificada em ordem decrescente (reversa).

# 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']

💡 Dica: Observe como a lista é classificada em ordem decrescente se reverse é True.

Chave

Agora que você sabe trabalhar com o reverse parâmetro, vamos ver o key parâmetro.

Esse parâmetro é um pouco mais detalhado porque determina como os elementos da lista são comparados durante o processo de classificação.

image 120
Sintaxe básica

O valor de key é também:

  • None, o que significa que os elementos da lista serão comparados diretamente. Por exemplo, em uma lista de números inteiros, os próprios números inteiros podem ser usados ​​para a comparação.
  • UMA função de um argumento que gera um valor intermediário para cada elemento. Esse valor intermediário é calculado apenas uma vez e é usado para fazer comparações durante todo o processo de classificação. Usamos isso quando não queremos comparar os elementos diretamente, por exemplo, quando queremos comparar seqüências de caracteres com base em seu comprimento (o valor intermediário).

💡 Dica: Por padrão, o valor de key é None, para que os elementos sejam comparados diretamente.

Por exemplo:

Digamos que queremos classificar uma lista de cadeias de caracteres com base em seu comprimento, da menor para a maior. Nós podemos passar a função len como o valor de key, como isso:

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

💡 Dica: Observe que estamos apenas passando o nome da função (len) sem parênteses, porque não estamos chamando a função Isto é muito importante.

Observe a diferença entre comparar os elementos diretamente e comparar seu comprimento (veja abaixo). Usando o valor padrão de key (None) classificariam as strings em ordem alfabética (esquerda), mas agora as classificamos com base em seu comprimento (direita):

image 49

O que acontece nos bastidores? Cada elemento é passado como argumento para o len() A função e o valor retornado por essa chamada de função são utilizados para realizar as comparações durante o processo de classificação:

image 122

Isso resulta em uma lista com um critério de classificação diferente: length.

Aqui temos outro exemplo:

Outro exemplo interessante é classificar uma lista de cadeias de caracteres como se todas fossem escritas em letras minúsculas (por exemplo, torne "Aa" equivalente a "aa").

De acordo com a ordem lexicográfica, as maiúsculas vêm antes das minúsculas:

>>> "E" < "e"True

Então a corda "Emma" viria antes "emily" em uma lista classificada, mesmo que suas versões em minúsculas estivessem na ordem oposta:

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

Para evitar distinguir entre letras maiúsculas e minúsculas, podemos passar a função str.lower Como key. Isso irá gerar uma versão em minúscula das seqüências de caracteres que serão usadas para as comparações:

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

Observe que agora, "emily" vem antes "Emma" na lista classificada, exatamente o que queríamos.

💡 Dica: se tivéssemos usado o processo de classificação padrão, todas as cadeias iniciadas com uma letra maiúscula teriam antes de todas as cadeias iniciadas com uma letra minúscula:

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

E ... Este é um exemplo usando Programação Orientada a Objetos (OOP):

Se tivermos essa classe Python muito simples:

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

E criamos quatro instâncias:

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

Podemos fazer uma lista que os referencie:

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

Então, se definirmos uma função para obter o age destas instâncias:

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

Podemos classificar a lista com base na idade deles, passando a função como argumento:

>>> clients.sort(key=get_age)

Esta é a versão final e classificada da lista. Usamos um loop for para imprimir a idade das instâncias na ordem em que aparecem na lista:

>>> for client in clients:	print(client.age)	13233567

Exatamente o que queríamos, agora a lista é classificada em ordem crescente, com base na idade das instâncias.

💡 Dica: Em vez de definir um get_age função, poderíamos ter usado uma função lambda para obter a idade de cada instância, assim:

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

Funções Lambda são funções anônimas pequenas e simples, o que significa que elas não têm nome. Eles são muito úteis para esses cenários, quando queremos apenas usá-los em locais específicos por um período muito curto.

Esta é a estrutura básica da função lambda que estamos usando para classificar a lista:

image 90
Estrutura básica de uma função Lambda

Passando ambos os argumentos

Impressionante! Agora você sabe personalizar a funcionalidade do sort() método, mas você pode elevar suas habilidades a um nível totalmente novo combinando o efeito de key e reverse na mesma chamada de método:

>>> f = ["A", "a", "B", "b", "C", "c"]>>> f.sort(key=str.lower, reverse=True)>>> f['C', 'c', 'B', 'b', 'A', 'a']
Classifique a lista na ordem inversa, como se as strings estivessem em minúsculas.

Estas são as diferentes combinações dos argumentos e seus efeitos:

image 124

A ordem dos argumentos apenas de palavras-chave não importa

Como estamos especificando os nomes dos argumentos, já sabemos qual valor corresponde a qual parâmetro, portanto, podemos incluir: key ou reverse primeiro na lista e o efeito será exatamente o mesmo.

Portanto, este método chama:

image 53

É equivalente a:

image 54

Isto é um exemplo:

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

Se mudarmos a ordem dos argumentos, obteremos exatamente o mesmo resultado:

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

🔹 Valor de retorno

Agora vamos falar um pouco sobre o valor de retorno desse método. o sort() método retorna None, faz não retorne uma versão classificada da lista, como poderíamos esperar intuitivamente.

De acordo com Documentação Python:

Para lembrar aos usuários que opera por efeito colateral, ele não retorna a sequência classificada.

Basicamente, isso é usado para nos lembrar que estamos modificando a lista original na memória, não gerando uma nova cópia da lista.

Este é um exemplo do valor de retorno de 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

Vejo? None foi retornado pela chamada do método

💡 Dica: É muito importante não confundir o sort() método com o sorted() função, que é uma função que funciona de maneira muito semelhante, mas não modifique a lista original (ela gera e retorna uma nova cópia da lista, já classificada).

Este é um exemplo que podemos usar para compará-los:

# The sort() method returns None>>> nums = [6.5, 2.4, 7.3, 3.5, 2.6, 7.4]>>> val = nums.sort()>>> print(val)None
Exemplo de .sort ()

# sorted() returns a new list, a 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]
Exemplo de classificado ()

Isso é muito importante porque o efeito deles é muito diferente. Usando o sort() método quando você pretendia usar sorted() pode introduzir erros sérios no seu programa porque você pode não perceber que a lista está sendo alterada.

🔸 O método sort () executa uma classificação estável

Agora, vamos falar um pouco sobre as características do algoritmo de classificação usado pelo sort().

Esse método executa uma classificação estável porque trabalha com uma implementação de TimSort, um algoritmo de classificação muito eficiente e estável.

De acordo com Documentação Python:

Uma classificação é estável se garantir para não alterar a ordem relativa dos elementos que comparam - isso é útil para classificar várias passagens (por exemplo, classificar por departamento e depois por nível salarial).

Isso significa que, se dois elementos tiverem o mesmo valor ou valor intermediário (chave), eles ficarão na mesma ordem em relação um ao outro.

Vamos ver o que quero dizer com isso. Veja este exemplo por alguns momentos:

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

Estamos comparando os elementos com base em suas comprimento porque passamos a len funcionar como argumento para key.

Podemos ver que existem três elementos com o comprimento 2: "BB", "AA"e "CC" naquela ordem.

Agora, observe que esses três elementos estão na mesma ordem relativa na lista final classificada:

image 92

Isso ocorre porque é garantido que o algoritmo é estável e os três tiveram o mesmo valor intermediário (chave) durante o processo de classificação (o comprimento deles era 2, então a chave era 2).

💡 Dica: O mesmo aconteceu com "A" e "B" (comprimento 1) e "AAA" e "BBB" (comprimento 3), sua ordem original em relação à outra foi preservada.

Agora você sabe como o sort() método funciona, então vamos mergulhar na mutação e em como ela pode afetar seu programa.

🔹 Mutação e riscos

Como prometido, vamos ver como o processo de mutação funciona nos bastidores:

Quando você define uma lista em Python, assim:

a = [1, 2, 3, 4]

Você cria um objeto em um local específico da memória. Esse local é chamado de "endereço de memória" do objeto, representado por um número inteiro exclusivo chamado Eu iria.

Você pode pensar em um ID como uma "tag" usada para identificar um local específico na memória:

image 40

Você pode acessar o ID de uma lista usando o id() , passando a lista como argumento:

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

Quando você mudar Na lista, você a altera diretamente na memória. Você pode perguntar, por que isso é tão arriscado?

É arriscado porque afeta todas as linhas de código que usam a lista após a mutação; portanto, você pode escrever um código para trabalhar com uma lista completamente diferente da lista real que existe na memória após a mutação.

É por isso que você precisa ter muito cuidado com os métodos que causam mutação.

Em particular, o sort() método muda a lista. Este é um exemplo de seu efeito:

image 94

Aqui está um exemplo:

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

A lista foi alterada após a chamada .sort().

Cada linha de código que funciona com a lista a após a ocorrência da mutação, a nova versão classificada da lista será usada. Se não foi o que você pretendia, talvez você não saiba que outras partes do seu programa estão trabalhando com a nova versão da lista.

Aqui está outro exemplo dos riscos de mutação dentro de uma função:

# 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)1357# Oops! The original list was mutated.>>> a[1, 3, 5, 7]

A lista a isso foi passado quando o argumento foi modificado, mesmo que não fosse o que você pretendia quando escreveu inicialmente a função.

💡 Dica: Se uma função modifica um argumento, deve ser claramente indicado para evitar esse tipo de problema que definitivamente pode introduzir bugs no seu programa.

🔸 Resumo do método sort ()

  • o sort() O método permite classificar uma lista em ordem crescente ou decrescente.
  • São necessários dois argumentos apenas de palavra-chave: key e reverse.
  • reverse determina se a lista é classificada em ordem crescente ou decrescente.
  • key é uma função que gera um valor intermediário para cada elemento e esse valor será usado para fazer as comparações durante o processo de classificação.
  • o sort() O método muda a lista, causando alterações permanentes. Você precisa ter muito cuidado e usá-lo apenas se não precisar da versão original da lista.

Eu realmente espero que você tenha gostado do meu artigo e que tenha sido útil. Agora você pode trabalhar com o sort() método em seus projetos Python. Confira meus cursos on-line. Siga-me no Twitter. 👍