Tri Python

Le moyen le plus simple d'effectuer un tri est d'utiliser la fonction separate(list), qui prend une liste et renvoie une nouvelle liste avec ces éléments dans l'ordre. La liste d'origine n'est pas modifiée.

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

Il est plus courant de transmettre une liste à la fonction triée(), mais elle peut en réalité prendre en entrée n'importe quel type de collection itérable. L'ancienne méthode list.sort() est une alternative détaillée ci-dessous. La fonction Sort() semble plus facile à utiliser que sort(), donc je vous recommande d'utiliser tri().

La fonction triés() peut être personnalisée au moyen d'arguments facultatifs. L'argument facultatif separate() inverse=True, par exemple, trié(liste, inversé=True), permet d'effectuer un tri dans l'ordre inverse.

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

Tri personnalisé avec la clé=

Pour un tri personnalisé plus complexe, fill() utilise une option "key=" facultative spécifiant une fonction "key" qui transforme chaque élément avant la comparaison. La fonction clé prend une valeur et renvoie une valeur, et la valeur "proxy" renvoyée est utilisée pour les comparaisons au sein du tri.

Par exemple, pour une liste de chaînes, spécifier key=len (la fonction intégrée len()) trie les chaînes par longueur, de la plus courte à la plus longue. Le tri appelle len() pour chaque chaîne afin d’obtenir la liste des valeurs de longueur proxy, puis effectue un tri avec ces valeurs proxy.

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

appel triés avec key=len

Autre exemple, spécifier "str.lower" comme fonction clé est un moyen de forcer le tri à traiter de la même manière les majuscules et les minuscules:

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

Vous pouvez également transmettre votre propre MyFn en tant que fonction clé, comme ceci:

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

Pour un tri plus complexe tel que le tri par nom de famille, puis par prénom, vous pouvez utiliser les fonctions itemgetter ou attrgetter comme suit:

  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éthode sort()

Au lieu d'une alternative à triée(), la méthode sort() sur une liste trie cette liste dans l'ordre croissant, par exemple list.sort(). La méthode sort() modifie la liste sous-jacente et renvoie la valeur None. Utilisez-la donc comme suit:

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

Ce qui précède est un malentendu très courant avec sort() -- il *ne renvoie pas* la liste triée. La méthode sort() doit être appelée sur une liste ; elle ne fonctionne sur aucune collection énumérable (mais la fonction triée() ci-dessus fonctionne sur tous les éléments). La méthode sort() est antérieure à la fonction triée(). Vous la verrez donc probablement dans un code plus ancien. La méthode sort() n'a pas besoin de créer une nouvelle liste, elle peut donc être un peu plus rapide si les éléments à trier sont déjà dans une liste.

Tuples

Un tuple est un groupe d'éléments de taille fixe, par exemple une coordonnées (x, y). Les tuples sont semblables à des listes, sauf qu'ils sont immuables et ne changent pas de taille (les tuples ne sont pas strictement immuables, car l'un des éléments contenus peut être mutable). Les tuples jouent un rôle en quelque sorte "struct" en Python : un moyen pratique de transmettre un petit groupe de valeurs logique et de taille fixe. Une fonction qui doit renvoyer plusieurs valeurs peut simplement renvoyer un tuple des valeurs. Par exemple, si je veux avoir une liste de coordonnées 3D, la représentation Python naturelle serait une liste de tuples, où chaque tuple de taille 3 contiendrait un groupe (x, y, z).

Pour créer un tuple, répertoriez simplement les valeurs entre parenthèses, séparées par des virgules. Le tuple "vide" n'est qu'une paire de parenthèses vide. L'accès aux éléments d'un tuple est comme une liste : len(), [ ], for, in, etc. fonctionnent tous de la même manière.

  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

Pour créer un tuple size-1, l'élément unique doit être suivi d'une virgule.

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

Il s'agit d'un cas amusant dans la syntaxe, mais la virgule est nécessaire pour distinguer le tuple du cas ordinaire, consistant à placer une expression entre parenthèses. Dans certains cas, vous pouvez omettre la parenthèse. Python verra alors à partir des virgules que vous souhaitez un tuple.

L'attribution d'un tuple à un tuple de noms de variables de taille identique attribue toutes les valeurs correspondantes. Si les tuples ne sont pas de la même taille, une erreur est générée. Cette fonctionnalité est également disponible pour les listes.

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

Compréhensions de liste (facultatif)

La compréhension des listes est une fonctionnalité plus avancée, utile dans certains cas, mais qui n'est pas nécessaire pour les exercices et ne nécessite pas d'apprentissage préalable (vous pouvez ignorer cette section, par exemple). La compréhension de liste est un moyen compact d'écrire une expression qui s'étend à toute une liste. Supposons que nous ayons une liste nums [1, 2, 3, 4]. Voici la compréhension de la liste pour calculer une liste de leurs carrés [1, 4, 9, 16]:

  nums = [1, 2, 3, 4]

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

La syntaxe est [ expr for var in list ] : for var in list ressemble à une boucle For standard, mais sans le signe deux-points (:). Le expr à sa gauche est évalué une fois pour chaque élément afin de fournir les valeurs de la nouvelle liste. Voici un exemple avec des chaînes, où chaque chaîne est remplacée par des majuscules avec le suffixe "!!!" :

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

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

Vous pouvez ajouter un test "if" à droite de la boucle "for" pour affiner les résultats. Le test "if" est évalué pour chaque élément, en incluant uniquement ceux pour lesquels le test est vrai.

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

Exercice: list1.py

Pour vous entraîner à utiliser les éléments de cette section, essayez les problèmes ultérieurs dans list1.py qui utilisent le tri et les tuples (dans les exercices de base).