Classificação Python

A maneira mais fácil de classificar é com a função classify(list), que pega uma lista e retorna uma nova lista com esses elementos na ordem ordenada. A lista original não é alterada.

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

É mais comum passar uma lista para a função scheduled(), mas, na verdade, ela pode receber como entrada qualquer tipo de coleção iterável. O método list.sort() mais antigo é uma alternativa detalhada abaixo. A função arrange() parece mais fácil de usar em comparação com sort(), então eu recomendo usar oSort().

A função arrange() pode ser personalizada com argumentos opcionais. O argumento opcional arrange() reverse=True, por exemplo, arrange(list, reverse=True), faz com que a classificação seja decrescente.

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

Classificação personalizada com key=

Para uma classificação personalizada mais complexa, a função vai ter uma "key=" opcional que especifica uma função "key" (chave) que transforma cada elemento antes da comparação. A função chave recebe um valor e retorna um valor, e o valor "proxy" retornado é usado para as comparações dentro da classificação.

Por exemplo, com uma lista de strings, especificar key=len (a função integrada len()) classifica as strings por tamanho, do mais curto ao mais longo. A classificação chama len() para cada string para receber a lista de valores de comprimento de proxy e, em seguida, classifica com esses valores de proxy.

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

chamadas ordenadas com key=len

Como outro exemplo, especificar "str.lower" como a função-chave é uma maneira de forçar a classificação a tratar maiúsculas e minúsculas da mesma forma:

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

Você também pode transmitir sua própria MyFn como a função principal, desta forma:

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

Para classificações mais complexas, como classificar por sobrenome e depois por nome, use as funções itemgetter ou attrgetter como:

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

Método sort()

Como alternativa a sort(), o método sort() de uma lista classifica essa lista em ordem crescente, por exemplo, list.sort(). O método sort() muda a lista subjacente e retorna None, portanto, use-o assim:

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

O exemplo acima é um mal-entendido muito comum com a função sort() - ela *não retorna* a lista classificada. O método sort() deve ser chamado em uma lista. Ele não funciona em nenhuma coleção enumerável (mas a função classify() acima funciona em qualquer coisa). O método sort() é anterior à função arrange(), então você provavelmente vai vê-lo em código mais antigo. O método sort() não precisa criar uma nova lista, portanto, pode ser um pouco mais rápido caso os elementos a serem classificados já estejam em uma lista.

Tuplas

Tupla é um agrupamento de elementos de tamanho fixo, como uma coordenada (x, y). As tuplas são como listas, mas são imutáveis e não mudam de tamanho. Elas não são estritamente imutáveis, já que um dos elementos contidos pode ser mutável. As tuplas desempenham um tipo de papel "struct" no Python: uma maneira conveniente de passar um pequeno pacote lógico e de tamanho fixo de valores. Uma função que precisa retornar diversos valores pode simplesmente retornar uma tupla dos valores. Por exemplo, se eu quisesse ter uma lista de coordenadas 3-d, a representação natural de Python seria uma lista de tuplos, em que cada tuplo tem tamanho 3 contendo um grupo (x, y, z).

Para criar uma tupla, basta listar os valores entre parênteses separados por vírgulas. A tupla "empty" é apenas um par vazio de parênteses. O acesso aos elementos em uma tupla é como em uma lista: len(), [ ], for, in etc. funcionam da mesma forma.

  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

Para criar uma tupla de tamanho 1, o elemento único precisa ser seguido por uma vírgula.

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

É um caso engraçado na sintaxe, mas a vírgula é necessária para distinguir a tupla do caso comum de colocar uma expressão entre parênteses. Em alguns casos, é possível omitir o parêntese e o Python verá entre as vírgulas a definição de uma tupla.

A atribuição de uma tupla a uma tupla de tamanho idêntico de nomes de variáveis atribui todos os valores correspondentes. Se as tuplas não forem do mesmo tamanho, um erro será exibido. Esse recurso também funciona para listas.

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

Listar compreensão (opcional)

As compreensãos de lista são um recurso mais avançado que é bom para alguns casos, mas não é necessário para os exercícios e não é algo que você precisa aprender no início (ou seja, você pode pular esta seção). Uma compreensão de lista é uma maneira compacta de escrever uma expressão que se expande para uma lista inteira. Suponha que temos uma lista nums [1, 2, 3, 4]. Esta é a compreensão da lista para calcular uma lista dos seus quadrados [1, 4, 9, 16]:

  nums = [1, 2, 3, 4]

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

A sintaxe é [ expr for var in list ] -- o for var in list parece um for-loop normal, mas sem os dois-pontos (:). A expr à esquerda é avaliada uma vez para cada elemento a fim de fornecer os valores para a nova lista. Veja um exemplo com strings, em que cada string é alterada para letras maiúsculas com "!!!" anexado:

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

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

É possível adicionar um teste if à direita do for-loop para restringir o resultado. O teste é avaliado para cada elemento, incluindo apenas os elementos em que o teste é verdadeiro.

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

Exercício: list1.py

Para praticar o material desta seção, tente outros problemas em list1.py que usam classificação e tuplas (nos Exercícios básicos).