1 – Dictionnaires
Les dictionnaires se révèlent très pratiques lorsque vous devez manipuler des structures complexes à décrire et que les listes présentent leurs limites. Les dictionnaires sont des collections non ordonnées d’objets, c-à-d qu’il n’y a pas de notion d’ordre (i. e. pas d’indice). On accède aux valeurs d’un dictionnaire par des clés. Ceci semble un peu confus ? Regardez l’exemple suivant :
Code python
>>> ani1 = {}
>>> ani1[‘nom’] = ‘girafe’
>>> ani1[‘taille’] = 5.0
>>> ani1[‘poids’] = 1100
>>> ani1
{‘nom’: ‘girafe’, ‘poids’: 1100, ‘taille’: 5.0}
>>> ani1[‘taille’]
5.0
En premier, on définit un dictionnaire vide avec les symboles {} (tout comme on peut le faire pour les listes avec []). Ensuite, on remplit le dictionnaire avec différentes clés auxquelles on affecte des valeurs (une par clé). Vous pouvez mettre autant de clés que vous voulez dans un dictionnaire (tout comme vous pouvez ajouter autant d’éléments que vous voulez dans une liste). Pour récupérer la valeur d’une clé donnée, il suffit d’utiliser une syntaxe du style dictionnaire[‘cle’].
Méthodes keys() et values()
Les méthodes keys() et values() renvoient, comme vous vous en doutez, les clés et les valeurs d’un dictionnaire (sous forme de liste) :
Code python
>>> ani1.keys()
[‘nom’, ‘poids’, ‘taille’]
>>> ani1.values()
[‘girafe’, 1100, 5.0]
On peut aussi initialiser toutes les clés d’un dictionnaire en une seule opération :
Code python
>>> ani2 = {‘nom’:’singe’, ‘poids’:70, ‘taille’:1.75}
Liste de dictionnaires
En créant une liste de dictionnaires possédant les mêmes clés, on obtient une structure qui ressemble à une base de données :
Code python
>>> animaux = [ani1, ani2]
>>> animaux
[{‘nom’: ‘girafe’, ‘poids’: 1100, ‘taille’: 5.0}, {‘nom’: ‘singe’, ‘poids’: 70, ‘taille’: 1.75}]
>>>
>>> for ani in animaux:
… print ani[‘nom’]
…
girafe
singe
Existence d’une clef
Enfin, pour vérifier si une clé existe, vous pouvez utiliser la propriété has_key():
Code python
>>> if ani2.has_key(‘poids’):
… print « La clef ‘poids’ existe pour ani2 »
…
La clef ‘poids’ existe pour ani2
Python permet même de simplifier encore les choses :
Code python
>>> if « poids » in ani2:
… print « La clef ‘poids’ existe pour ani2 »
…
La clef ‘poids’ existe pour ani2
Vous voyez que les dictionnaires permettent de gérer des structures complexes de manière plus explicite que les listes.
2 – Tuples
Les tuples correspondent aux listes à la différence qu’ils sont non modifiables. On a vu à la section précédente que les listes pouvaient être modifiées par des références; les tuples vous permettent de vous affranchir de ce problème. Pratiquement, ils utilisent les parenthèses au lieu des crochets :
Code python
>>> x = (1,2,3)
>>> x
(1, 2, 3)
>>> x[2]
3
>>> x[0:2]
(1, 2)
>>> x[2] = 15
Traceback (innermost last):
File « <stdin> », line 1, in ?
TypeError: object doesn’t support item assignment
L’affectation et l’indiçage fonctionne comme avec les listes, mais si l’on essaie de modifier un des éléments du tuple, Python renvoie un message d’erreur. Si vous voulez ajouter un élément (ou le modifier), vous devez créer un autre tuple :
>>> x = (1,2,3)
>>> x + (2,)
(1, 2, 3, 2)
Remarquez que pour utiliser un tuple d’un seul élément, vous devez utiliser une syntaxe avec une virgule (element,), ceci pour éviter une ambiguïté avec une simple expression. Autre particularité des tuples, il est possible d’en créer de nouveaux sans les parenthèses, dès lors que ceci ne pose pas d’ambiguïté avec une autre expression :
Code python
>>> x = (1,2,3)
>>> x
(1, 2, 3)
>>> x = 1,2,3
>>> x
(1, 2, 3)
Toutefois, nous vous conseillons d’utiliser systématiquement les parenthèses afin d’éviter les confusions.
Enfin, on peut utiliser la fonction tuple(sequence) qui fonctionne exactement comme la fonction list, c-à-d qu’elle prend en argument un objet séquentiel et renvoie le tuple correspondant :
Code python
>>> range(10)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> tuple(range(10))
(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
>>> tuple(« ATGCCGCGAT »)
(‘A’, ‘T’, ‘G’, ‘C’, ‘C’, ‘G’, ‘C’, ‘G’, ‘A’, ‘T’)
Remarque : les listes, dictionnaires, tuples sont des objets qui peuvent contenir des collections d’autres objets. On peut donc construire des listes qui contiennent des dictionnaires, des tuples ou d’autres listes, mais aussi des dictionnaires contenant des tuples, des listes, etc.
3 – Exercices
Conseil : pour ces exercices, écrivez des scripts dans des fichiers, puis exécutez-les dans un shell.
En utilisant un dictionnaire et la fonction has_key(), déterminez le nombre d’occurences de chaque acide aminé dans la séquence AGWPSGGASAGLAILWGASAIMPGALW. Le dictionnaire ne doit contenir que les acides aminés présents dans la séquence.
Soit la séquence nucléotidique suivante :
ACCTAGCCATGTAGAATCGCCTAGGCTTTAGCTAGCTCTAGCTAGCTG
En utilisant un dictionnaire, faites un programme qui répertorie tous les mots de 2 lettres qui existent dans la sequence (AA, AC, AG, AT, etc.) ainsi que leur nombre d’occurences puis qui les affiche à l’écran.
Faites de même avec des mots de 3 et 4 lettres.
En vous basant sur les scripts précédents, extrayez les mots de 2 lettres et leur occurence sur le génome du chromosome I de la levure du boulanger Saccharomyces cerevisiae NC_001133.fna. Attention, le génome complet est fourni au format fasta.
Créez un script extract-words.py qui prend en arguments un fichier genbank suivi d’un entier compris entre 1 et 4. Ce script doit extraire du fichier genbank tous les mots (ainsi que leur nombre d’occurences) du nombre de lettres passées en option.
Appliquez ce script sur le génome d’Escherichia coli : NC_000913.fna (au format fasta). Cette méthode vous paraît-elle efficace sur un génome assez gros comme celui d’E. Coli ? Comment pourrait-on en améliorer la rapidité ?
À partir du fichier PDB 1BTA, construisez un dictionnaire qui contient 4 clés se référant au premier carbone alpha : le numéro du résidu, puis les coordonnées x, y et z.
Sur le même modèle que ci-dessus, créez une liste de dictionnaires pour chacun des carbones alpha de la protéine.
À l’aide de cette liste, calculez les coordonnées x, y et z du barycentre de ces carbones alpha.