Un list est une collection mutable d'éléments en séquence.
Comme la plupart des collections (voir les types natifs tuple, dict et set), les tableaux peuvent contenir des références vers n'importe quel type de données, voire plusieurs, y compris d'autres tableaux.
Comme pour toute séquence, on peut accéder aux éléments par un 0-based index depuis la gauche et un -1-based index depuis la droite.
On peut copier un tableau en totalité ou en partie via la notation de tranche ou <list>.copy().
Les tableaux prennent en charge les opérations de séquence communes et mutables, telles que min()/max(), <list>.index(), <list>.append() et <list>.reverse().
On peut parcourir les éléments d'un tableau avec la construction for item in <list>.
On peut utiliser for index, item in enumerate(<list>) quand on a besoin à la fois de l'indice et de la valeur de l'élément.
Sous le capot, les lists sont implémentés comme des tableaux dynamiques, similaires au type ArrayList de Java ; ils servent le plus souvent à stocker des groupes de données similaires (strings, nombres, ensembles, etc.) de longueur inconnue.
Les tableaux sont une structure de données extrêmement flexible et utile, et de nombreuses méthodes et opérations natives de Python produisent des tableaux en sortie.
Un list peut être déclaré sous forme de littéral avec des crochets [] et des virgules entre les éléments :
>>> no_elements = []
>>> no_elements
[]
>>> one_element = ["Guava"]
>>> one_element
['Guava']
>>> elements_separated_with_commas = ["Parrot", "Bird", 334782]
>>> elements_separated_with_commas
['Parrot', 'Bird', 334782]
Pour plus de lisibilité, on peut utiliser des retours à la ligne quand un list contient beaucoup d'éléments ou des structures de données imbriquées :
>>> lots_of_entries = [
"Rose",
"Sunflower",
"Poppy",
"Pansy",
"Tulip",
"Fuchsia",
"Cyclamen",
"Lavender"
]
>>> lots_of_entries
['Rose', 'Sunflower', 'Poppy', 'Pansy', 'Tulip', 'Fuchsia', 'Cyclamen', 'Lavender']
# Each data structure is on its own line to help clarify what they are.
>>> nested_data_structures = [
{"fish": "gold", "monkey": "brown", "parrot": "grey"},
("fish", "mammal", "bird"),
['water', 'jungle', 'sky']
]
>>> nested_data_structures
[{'fish': 'gold', 'monkey': 'brown', 'parrot': 'grey'}, ('fish', 'mammal', 'bird'), ['water', 'jungle', 'sky']]
Le constructeur list() peut être utilisé vide ou avec un itérable comme argument.
Le constructeur parcourt les éléments de l'itérable et les ajoute au list dans l'ordre :
>>> no_elements = list()
>>> no_elements
[]
# The tuple is unpacked and each element is added.
>>> multiple_elements_from_tuple = list(("Parrot", "Bird", 334782))
>>> multiple_elements_from_tuple
['Parrot', 'Bird', 334782]
# The set is unpacked and each element is added.
>>> multiple_elements_from_set = list({2, 3, 5, 7, 11})
>>> multiple_elements_from_set
[2, 3, 5, 7, 11]
Les résultats obtenus en utilisant un constructeur list avec une string ou un dict peuvent surprendre :
# String elements (Unicode code points) are iterated through and added *individually*.
>>> multiple_elements_string = list("Timbuktu")
>>> multiple_elements_string
['T', 'i', 'm', 'b', 'u', 'k', 't', 'u']
# Unicode separators and positioning code points are also added *individually*.
>>> multiple_code_points_string = list('अभ्यास')
>>> multiple_code_points_string
['अ', 'भ', '्', 'य', 'ा', 'स']
# The iteration default for dictionaries is over the keys, so only key data is inserted into the list.
>>> source_data = {"fish": "gold", "monkey": "brown"}
>>> multiple_elements_dict_1 = list(source_data)
['fish', 'monkey']
Comme le constructeur list n'accepte que des itérables (ou rien) comme arguments, les objets qui ne sont pas itérables lèvent une erreur de type.
Par conséquent, il est bien plus simple de créer un list à un seul élément avec la méthode littérale.
# Numbers are not iterable, and so attempting to create a list with a number passed to the constructor fails.
>>> one_element = list(16)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'int' object is not iterable
# Tuples *are* iterable, so passing a one-element tuple to the constructor does work, but it's awkward
>>> one_element_from_iterable = list((16,))
>>> one_element_from_iterable
[16]
On peut accéder aux éléments d'un tableau (ainsi qu'aux éléments d'autres types de séquence comme str et tuple) via un 0-based index et la notation entre crochets.
Les indices peuvent aller de la left vers la right (en partant de zéro) ou de la right vers la left (en partant de -1).
| indice en partant de la gauche ⟹ |
|
⟸ indice en partant de la droite |
>>> breakfast_foods = ["Oatmeal", "Fruit Salad", "Eggs", "Toast"]
# Oatmeal is at index 0 or index -4.
>>> breakfast_foods[0]
'Oatmeal'
>>> breakfast_foods[-4]
'Oatmeal'
# Eggs are at index -2 or 2
>>> breakfast_foods[-2]
'Eggs'
>>> breakfast_foods[2]
'Eggs'
# Toast is at -1
>>> breakfast_foods[-1]
'Toast'
On peut accéder à une section des éléments d'un list via la notation de tranche (<list>[start:stop]).
Une tranche est définie comme une séquence d'éléments aux positions index, telles que start <= index < stop.
Le découpage renvoie une copie des éléments « découpés » et ne modifie pas le list d'origine.
On peut aussi utiliser un paramètre step [start:stop:step] pour « sauter » ou filtrer les éléments du list (par exemple, un step de 2 sélectionnera un élément sur deux dans l'intervalle) :
>>> colors = ["Red", "Purple", "Green", "Yellow", "Orange", "Pink", "Blue", "Grey"]
# If there is no step parameter, the step is assumed to be 1.
>>> middle_colors = colors[2:6]
>>> middle_colors
['Green', 'Yellow', 'Orange', 'Pink']
# If the start or stop parameters are omitted, the slice will
# start at index zero, and will stop at the end of the list.
>>> primary_colors = colors[::3]
>>> primary_colors
['Red', 'Yellow', 'Blue']
Utiliser la fonction native sum() sur un tableau renvoie la somme de tous les nombres du tableau :
>>> number_list = [1, 2, 3, 4]
>>> sum(number_list)
10
On peut aussi obtenir la longueur d'un tableau avec la fonction len() :
>>> long_list = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J"]
>>> len(long_list)
10
Les tableaux peuvent aussi être combinés de différentes manières :
# Using the plus + operator unpacks each list and creates a new list, but it is not efficient.
>>> new_via_concatenate = ["George", 5] + ["cat", "Tabby"]
>>> new_via_concatenate
['George', 5, 'cat', 'Tabby']
# Likewise, using the multiplication operator * is the equivalent of using + n times.
>>> first_group = ["cat", "dog", "elephant"]
>>> multiplied_group = first_group * 3
>>> multiplied_group
['cat', 'dog', 'elephant', 'cat', 'dog', 'elephant', 'cat', 'dog', 'elephant']
Un tableau fournit un itérateur et peut être parcouru de la même manière que les autres types de séquence.
# Looping through the list and printing out each element.
>>> colors = ["Orange", "Green", "Grey", "Blue"]
>>> for item in colors:
... print(item)
...
Orange
Green
Grey
Blue
Pour une explication plus approfondie des loops et des iterators, termine le concept loops.
Elyse a vraiment hâte de jouer au poker (et à d'autres jeux de cartes) lors de son prochain voyage à Vegas. Grande amatrice de « self-tracking », elle veut écrire quelques petites fonctions qui l'aideront dans ses tâches de suivi, et elle t'a demandé de l'aider à réfléchir à leur conception.
Elyse a un faible tout particulier pour le poker et veut suivre le nombre de manches qu'elle joue, et surtout lesquelles. Chaque manche porte son propre numéro, et chaque table affiche le numéro de la manche en cours. Elyse choisit une table et s'installe pour jouer sa première manche. Elle compte jouer trois manches.
Implémente une fonction get_rounds(<round_number>) qui prend le numéro de la manche en cours et renvoie un seul list contenant cette manche et les deux suivantes :
>>> get_rounds(27)
[27, 28, 29]
Elyse a joué quelques manches à la première table, puis a fait une pause et a joué d'autres manches à une deuxième table... mais elle s'est retrouvée avec un tableau différent pour chaque table ! Elle veut réunir les deux tableaux pour pouvoir suivre toutes ses manches de poker au même endroit.
Implémente une fonction concatenate_rounds(<rounds_1>, <rounds_2>) qui prend deux tableaux et renvoie un seul list composé de toutes les manches du premier tableau, suivies de toutes les manches du second tableau :
>>> concatenate_rounds([27, 28, 29], [35, 36])
[27, 28, 29, 35, 36]
En parlant de certaines manches de poker précédentes, un autre joueur fait remarquer que deux d'entre elles se sont déroulées de façon très similaire. Elyse ne sait pas trop si elle a joué ces manches ou non.
Implémente une fonction list_contains_round(<rounds>, <round_number>) qui prend deux arguments : un tableau des manches jouées et un numéro de manche.
La fonction renvoie True si la manche figure dans le tableau des manches jouées, et False sinon :
>>> list_contains_round([27, 28, 29, 35, 36], 29)
True
>>> list_contains_round([27, 28, 29, 35, 36], 30)
False
Elyse veut essayer un nouveau jeu appelé Black Joe. Il ressemble au Black Jack, où l'objectif est d'atteindre une valeur cible avec les cartes en main, mais dans Black Joe l'objectif est que la moyenne des valeurs des cartes soit égale à 7. On obtient cette moyenne en additionnant toutes les valeurs des cartes, puis en divisant cette somme par le nombre de cartes en main.
Implémente une fonction card_average(<hand>) qui renvoie la valeur moyenne d'une main de Black Joe.
>>> card_average([5, 6, 7])
6.0
Dans Black Joe, la rapidité compte. Elyse va chercher un moyen plus rapide de calculer la moyenne.
Elle a pensé à deux façons d'obtenir un nombre qui s'approche d'une moyenne :
Implémente la fonction approx_average_is_average(<hand>), où hand est un tableau contenant les valeurs des cartes de la main.
Renvoie True si l'une or les deux des stratégies nommées ci-dessus donnent un nombre égal à la moyenne réelle.
Remarque : la taille de toutes les mains est impaire, ce qui facilite la recherche de la médiane.
>>> approx_average_is_average([1, 2, 3])
True
>>> approx_average_is_average([2, 3, 4, 8, 8])
True
>>> approx_average_is_average([1, 2, 3, 5, 9])
False
Intriguée par les résultats de son expérience sur les moyennes, Elyse se demande si faire la moyenne des cartes aux positions paires d'un côté, et la moyenne des cartes aux positions impaires de l'autre, donnerait le même résultat. C'est l'heure d'une nouvelle fonction de test !
Implémente une fonction average_even_is_average_odd(<hand>) qui renvoie un booléen indiquant si la moyenne des cartes aux indices pairs est égale à la moyenne des cartes aux indices impairs.
>>> average_even_is_average_odd([1, 2, 3])
True
>>> average_even_is_average_odd([1, 2, 3, 4])
False
Dans Black Joe, une main sur onze est une main bonus, avec une règle spéciale : si la dernière carte que tu tires est un valet, tu doubles sa valeur.
Implémente une fonction maybe_double_last(<hand>) qui prend une main et vérifie si la dernière carte est un valet (11).
Si la dernière carte est un valet (11), double sa valeur avant de renvoyer la main.
>>> hand = [5, 9, 11]
>>> maybe_double_last(hand)
[5, 9, 22]
>>> hand = [5, 9, 10]
>>> maybe_double_last(hand)
[5, 9, 10]
Inscris-toi sur Exercism pour apprendre et maîtriser Python avec 17 concepts146 exercices, et un vrai mentorat humain, le tout gratuitement.