Chaînes Python

Python dispose d'une classe de chaîne intégrée nommée "str" avec de nombreuses fonctionnalités pratiques (il existe un ancien module nommé "string" que vous ne devez pas utiliser). Les littéraux de chaîne peuvent être délimités par des guillemets simples ou doubles, bien que des guillemets simples soient plus couramment utilisés. La barre oblique inverse fonctionne comme un échappement dans les littéraux entre guillemets simples et doubles, par exemple \n \' \". Un littéral de chaîne entre guillemets simples peut contenir des guillemets simples (par exemple, "Je ne l'ai pas fait") et les chaînes entre guillemets simples peuvent contenir des guillemets doubles. Un littéral de chaîne peut s'étendre sur plusieurs lignes, mais vous devez insérer une barre oblique inverse \ à la fin de chacune d'elles pour échapper la nouvelle ligne. Les littéraux de chaîne situés entre des guillemets triples (""" ou ''') peuvent s'étendre sur plusieurs lignes de texte.

Les chaînes Python sont "immuables", ce qui signifie qu'elles ne peuvent pas être modifiées après leur création (les chaînes Java utilisent également ce style immuable). Comme les chaînes ne peuvent pas être modifiées, nous construisons de *nouvelles* chaînes au fur et à mesure pour représenter les valeurs calculées. Ainsi, par exemple, l'expression ("hello" + 'there') utilise les deux chaînes "hello" et "there", puis crée une nouvelle chaîne "hellothere".

Les caractères d'une chaîne sont accessibles à l'aide de la syntaxe standard [ ], et comme Java et C++, Python utilise une indexation basée sur zéro, donc si s correspond à 'hello' s[1] est 'e'. Si l'index de la chaîne est hors limites, Python génère une erreur. Contrairement à Perl, le style Python consiste à s'arrêter s'il ne peut pas dire quoi faire au lieu de simplement définir une valeur par défaut. La syntaxe pratique de "tranche" (ci-dessous) permet également d'extraire n'importe quelle sous-chaîne d'une chaîne. La fonction len(string) renvoie la longueur d'une chaîne. La syntaxe [ ] et la fonction len() fonctionnent en fait sur n'importe quel type de séquence : chaînes, listes, etc. Python tente de faire fonctionner ses opérations de manière cohérente sur différents types. Piège pour les débutants en Python: n'utilisez pas "len" comme nom de variable pour éviter de bloquer la fonction len(). L'opérateur "+" peut concaténer deux chaînes. Notez dans le code ci-dessous que les variables ne sont pas prédéclarées : il vous suffit de les attribuer, puis c'est bon.

  s = 'hi'
  print(s[1])          ## i
  print(len(s))        ## 2
  print(s + ' there')  ## hi there

Contrairement à Java, le signe "+" ne convertit pas automatiquement les nombres ou d'autres types en chaîne. La fonction str() convertit les valeurs en un format de chaîne afin qu'elles puissent être combinées avec d'autres chaînes.

  pi = 3.14
  ##text = 'The value of pi is ' + pi      ## NO, does not work
  text = 'The value of pi is '  + str(pi)  ## yes

Pour les nombres, les opérateurs standards +, /, * fonctionnent de la manière habituelle. Il n'y a pas d'opérateur ++, mais +=, -=, etc. fonctionne. Si vous voulez utiliser une division entière, utilisez deux barres obliques (par exemple, 6 // 5 est 1).

La fonction "print" affiche généralement un ou plusieurs éléments Python suivis d'un saut de ligne. Un littéral de chaîne "brut" est précédé d'un "r" et transmet tous les caractères sans traitement spécial des barres obliques inverses. Par conséquent, r'x\nx' prend la valeur "x\nx" de longueur 4. La commande "print" peut nécessiter plusieurs arguments pour modifier la façon dont elle imprime les éléments (voir la définition de la fonction d'impression de python.org), par exemple définir "end" sur "" pour ne plus imprimer de nouvelle ligne une fois tous les éléments imprimés.

  raw = r'this\t\n and that'

  # this\t\n and that
  print(raw)

  multi = """It was the best of times.
  It was the worst of times."""

  # It was the best of times.
  #   It was the worst of times.
  print(multi)

Méthodes de chaîne

Voici quelques-unes des méthodes de chaîne les plus courantes. Une méthode est semblable à une fonction, mais elle s'exécute "sur" un objet. Si la variable s est une chaîne, alors le code s.lower() exécute la méthode lower() sur cet objet de chaîne et renvoie le résultat (l'idée d'une méthode exécutée sur un objet est l'une des idées de base qui constituent la programmation orientée objet). Voici quelques-unes des méthodes de chaîne les plus courantes:

  • s.lower(), s.upper() : renvoie la version en minuscules ou en majuscules de la chaîne.
  • s.strip() : renvoie une chaîne sans les espaces au début et à la fin.
  • s.isalpha()/s.isdigit()/s.isspace()... : vérifie si tous les caractères de chaîne se trouvent dans les différentes classes de caractères.
  • s.startswith('other'), s.endswith('other') : teste si la chaîne commence ou se termine par l'autre chaîne donnée.
  • s.find('other') : recherche l'autre chaîne donnée (et non une expression régulière) dans s et renvoie le premier index où elle commence ou -1 si elle est introuvable
  • s.replace('old', 'new') : renvoie une chaîne dans laquelle toutes les occurrences de 'old' ont été remplacées par 'new'.
  • s.split('delim') : renvoie une liste de sous-chaînes séparées par le délimiteur donné. Le délimiteur n'est pas une expression régulière, il s'agit simplement de texte. 'aaa,bbb,ccc'.split(',') -> ['aaa', 'bbb', 'ccc']. Comme cas particulier, s.split() (sans argument) effectue un fractionnement de tous les espaces blancs.
  • s.join(list) -- à l'opposé de "split()", joint les éléments de la liste donnée en utilisant la chaîne comme délimiteur. Exemple : '---'.join(['aaa', 'bbb', 'ccc']) -> aaa---bbb---ccc.

Une recherche Google sur "python str" devrait vous conduire aux méthodes de chaîne python.org officielles, qui répertorient toutes les méthodes str.

Python n'a pas de type de caractère distinct. À la place, une expression comme s[8] renvoie une chaîne-longueur-1 contenant le caractère. Avec cette chaîne-longueur-1, les opérateurs ==, <=, ... fonctionnent tous comme prévu. Vous n'avez donc généralement pas besoin de savoir que Python n'a pas de type scalaire "char" distinct.

Tranches de cordes

La syntaxe de "tranche" est un moyen pratique de faire référence aux sous-parties d'une séquence, généralement des chaînes et des listes. La tranche s[start:end] correspond aux éléments qui commencent par un début et s'étendent jusqu'à la fin (non incluse). Supposons que nous ayons s = "Bonjour"

la chaîne &quot;hello&quot; avec les lettres de 0 1 2 3 4

  • s[1:4] correspond à "ell" -- caractères commençant par l'index 1 et s'étendant jusqu'à l'index 4 (non inclus)
  • s[1:] correspond à "ello". Si vous omettez l'un ou l'autre index, le début ou la fin de la chaîne est défini par défaut.
  • "s[:]" correspond à "Hello". En omettant les deux, vous obtenez toujours une copie complète (il s'agit de la méthode Python pour copier une séquence, comme une chaîne ou une liste).
  • s[1:100] correspond à "ello" : un index trop volumineux est tronqué à la longueur de la chaîne.

Les numéros d'index standard basés sur zéro permettent d'accéder facilement aux caractères situés près du début de la chaîne. À la place, Python utilise des nombres négatifs pour faciliter l'accès aux caractères situés à la fin de la chaîne: s[-1] est le dernier caractère 'o', s[-2] est 'l' le dernier caractère, etc. Les numéros d'index négatifs commencent à être comptés à partir de la fin de la chaîne:

  • s[-1] correspond à "o" -- dernier caractère (1er à partir de la fin)
  • s[-4] correspond à "e" : 4 en partant de la fin
  • s[:-3] correspond à "Il". Il peut entrer les 3 derniers caractères, mais pas les trois.
  • s[-3:] correspond à "llo". Il commence par le 3e caractère en partant de la fin et s'étend jusqu'à la fin de la chaîne.

Il s'agit d'un truisme simple de tranches que pour tout indice n, s[:n] + s[n:] == s. Cela fonctionne même pour n négatif ou hors limites. Ou mettre d'une autre manière s[:n] et s[n:] partitionnent toujours la chaîne en deux parties, en conservant tous les caractères. Comme nous le verrons plus tard dans la section "Liste", les segments fonctionnent également avec les listes.

Mise en forme des chaînes

Python peut convertir automatiquement des objets en chaîne adaptée à l'impression. Pour ce faire, il existe deux méthodes intégrées : les littéraux de chaîne formatés, également appelés "chaînes f", et l'appel de str.format().

Littéraux de chaîne mis en forme

Des littéraux de chaîne mis en forme sont souvent utilisés dans les situations suivantes:

  value = 2.791514
  print(f'approximate value = {value:.2f}')  # approximate value = 2.79

  car = {'tires':4, 'doors':2}
  print(f'car = {car}') # car = {'tires': 4, 'doors': 2}

Une chaîne littérale mise en forme est précédée de "f" (comme le préfixe "r" utilisé pour les chaînes brutes). Tout texte en dehors des accolades "{}" est imprimé directement. Les expressions contenues dans "{}" sont imprimées selon la spécification de format décrite dans les spécifications du format.Vous pouvez effectuer de nombreuses opérations intéressantes concernant la mise en forme, y compris la troncation, la conversion en notation scientifique et l'alignement gauche/droite/centre.

Les chaînes f sont très utiles lorsque vous souhaitez imprimer un tableau d'objets et que les colonnes représentant différents attributs d'objet doivent être alignées comme

  address_book = [{'name':'N.X.', 'addr':'15 Jones St', 'bonus': 70},
      {'name':'J.P.', 'addr':'1005 5th St', 'bonus': 400},
      {'name':'A.A.', 'addr':'200001 Bdwy', 'bonus': 5},]

  for person in address_book:
    print(f'{person["name"]:8} || {person["addr"]:20} || {person["bonus"]:>5}')

  # N.X.     || 15 Jones St          ||    70
  # J.P.     || 1005 5th St          ||   400
  # A.A.     || 200001 Bdwy          ||     5

% de chaînes

Python dispose également d'une fonction plus ancienne de type printf() pour assembler une chaîne. L'opérateur % prend une chaîne au format printf à gauche (%d int, chaîne %s, %f/%g à virgule flottante) et les valeurs correspondantes dans un tuple à droite (un tuple se compose de valeurs séparées par des virgules, généralement regroupées entre parenthèses):

  # % operator
  text = "%d little pigs come out, or I'll %s, and I'll %s, and I'll blow your %s down." % (3, 'huff', 'puff', 'house')

La ligne ci-dessus est assez longue. Supposons que vous souhaitiez la diviser en lignes distinctes. Vous ne pouvez pas simplement diviser la ligne après "%" comme vous le feriez dans d'autres langages, puisque par défaut Python traite chaque ligne comme une instruction distincte (du côté plus, il n'est donc pas nécessaire de saisir des points-virgules sur chaque ligne). Pour résoudre ce problème, placez l'expression entière entre parenthèses. L'expression peut alors s'étendre sur plusieurs lignes. Cette technique de code sur plusieurs lignes fonctionne avec les différentes constructions de regroupement décrites ci-dessous: ( ), [ ], { }.

  # Add parentheses to make the long line work:
  text = (
    "%d little pigs come out, or I'll %s, and I'll %s, and I'll blow your %s down."
    % (3, 'huff', 'puff', 'house'))

C'est mieux, mais la file d'attente est encore un peu longue. Python vous permet de découper une ligne en morceaux qu'il concatène ensuite automatiquement. Donc, pour rendre cette ligne encore plus courte, nous pouvons faire ceci:

  # Split the line into chunks, which are concatenated automatically by Python
  text = (
    "%d little pigs come out, "
    "or I'll %s, and I'll %s, "
    "and I'll blow your %s down."
    % (3, 'huff', 'puff', 'house'))

Chaînes (Unicode ou octets)

Les chaînes Python standards sont Unicode.

Python accepte également les chaînes composées d'octets bruts (indiqués par le préfixe "b" devant un littéral de chaîne) comme:

> byte_string = b'A byte string'
> byte_string
  b'A byte string'

Une chaîne Unicode est un type d'objet différent d'une chaîne d'octets, mais diverses bibliothèques telles que les expressions régulières fonctionnent correctement si l'un ou l'autre de ces types de chaîne est transmis.

Pour convertir une chaîne Python standard en octets, appelez la méthode encode() sur la chaîne. Dans l'autre sens, la méthode decode() de type byte string (chaîne d'octets) convertit les octets bruts encodés en une chaîne Unicode:

> ustring = 'A unicode \u018e string \xf1'
> b = ustring.encode('utf-8')
> b
b'A unicode \xc6\x8e string \xc3\xb1'  ## bytes of utf-8 encoding. Note the b-prefix.
> t = b.decode('utf-8')                ## Convert bytes back to a unicode string
> t == ustring                         ## It's the same as the original, yay!

True

Dans la section de lecture de fichiers, vous trouverez un exemple montrant comment ouvrir un fichier texte avec un encodage et lire des chaînes Unicode.

Instruction if

Python n'utilise pas { } pour placer des blocs de code pour des fonctions if/boucles/fonctions, etc. À la place, Python utilise le signe deux-points (:) et le retrait ou l'espace blanc pour regrouper les instructions. Le test booléen d'un if n'a pas besoin d'être entre parenthèses (grande différence par rapport à C++/Java) et peut comporter des clauses *elif* et *else* (mnémonique: le mot "elif" a la même longueur que le mot "else").

N'importe quelle valeur peut être utilisée comme test if-test. Les valeurs "zéro" comptent toutes comme "false" : aucune, 0, chaîne vide, liste vide, dictionnaire vide. Il existe également un type booléen avec deux valeurs: True et False (convertis en entier, il s'agit de 1 et 0). Python utilise les opérations de comparaison habituelles: ==, !=, <, <=, >, >=. Contrairement à Java et C, == est surchargé pour fonctionner correctement avec des chaînes. Les opérateurs booléens sont les mots épelés *and*, *or* et *not* (Python n'utilise pas le style C && || !). Voici à quoi peut ressembler le code d'une application de santé proposant des recommandations de boissons tout au long de la journée. Notez que chaque bloc des instructions then/else commence par un : et les instructions sont regroupées par retrait:

  if time_hour >= 0 and time_hour <= 24:
    print('Suggesting a drink option...')
    if mood == 'sleepy' and time_hour < 10:
      print('coffee')
    elif mood == 'thirsty' or time_hour < 2:
      print('lemonade')
    else:
      print('water')

Je trouve que l'omission de ":" est l'erreur de syntaxe la plus courante lors de la saisie du type de code ci-dessus, probablement parce qu'il s'agit d'un élément supplémentaire à saisir par rapport à mes habitudes C++/Java. De plus, ne mettez pas le test booléen entre parenthèses : c'est une habitude C/Java. Si le code est court, vous pouvez le placer sur la même ligne après ":", comme ceci (cela s'applique également aux fonctions, aux boucles, etc.), même si certaines personnes trouvent qu'il est plus lisible d'espacer les éléments sur des lignes distinctes.

  if time_hour < 10: print('coffee')
  else: print('water')

Exercice: string1.py

Pour vous entraîner dans cette section, essayez l'exercice string1.py de la section Exercices de base.