Dictionnaires et codes génétiques

Dictionnaire

Un dictionnaire est une collection non ordonnée d'objets modifiables, accessibles par des clés. La clé d'un élément peut être un nombre (même "réel" ou complexe), une chaîne ou même un tuple (mais pas une liste ni un dictionnaire). En Python, il est associé au type dict. Les dictionnaires sont également appelés « tableaux de hachages » ou bien « tableaux associatifs ».

Syntaxe

Un dictionnaire est défini par l'une des syntaxe suivante

d = {cle1:valeur1, cle2:valeur2 ...}

ou

d = dict(cle1=valeur1,cle2=valeur)

>>> hindi={1:"ek", 2:"do", 3:"tin", 4:"char", 5:'panch'}

>>> hindi[1]

'ek'

>>> two=2

>>> hindi[two]

'do'

Accès

Un dictionnaire n'est pas une liste : on accède à la valeur d'un dictionnaire par sa clé, non par son indice

>>> hindi= {'un': 'ek', 'deux': 'do', 'trois': 'tin', 'quatre': 'char', 'cinq': 'panch'}

>>> print hindi["cinq"] # la clé est ici une chaîne

'panch'

>>> hindi[3]

KeyError: 3

Fonctions sur les dictionnaires

len(dico) renvoie le nombre de doublets clé:valeur d'un dictionnaire

all(dico) retourne True si aucune valeur d'un dictionnaire n'est fausse (le dictionnaire peut être vide)

any(dico) retourne True si au moins une valeur d'un dictionnaire est vraie (différent de 0, None, "", [], (), {}...)

type(dico) renvoie <type 'dict'>, mais comparer un dictionnaire avec la chaîne "<type 'dict'>" ne fonctionne pas, il faut utiliser type({}) :

>>> mondico={4:"spam",3:"egg"}

>>> type(mondico)==type({})

True

del(dico) détruit le dictionnaire dico

Le module anydbm permet de sauvegarder sur disque des dictionnaires de chaînes, le module shelve permet de sauvegarder également les autres objets de Python : nombres, tuples, listes, fichiers binaires (cf. annexes).

Fonctions sur les dictionnaires

flag=dico.has_key(clef) renvoie True si le dictionnaire dico contient la clé clef, c'est préférable pour ne pas appeler une clé qui n'existerait pas.

dico.get(cle) renvoie la valeur associée à la clé, None si la clé n'existe pas

dico.get(cle,exp) renvoie l'expression (qui peut-être un nombre, une chaîne...) si la valeur n'existe pas. C'est équivalent à la boucle :

if "trois" in hindi:

  print hindi["trois"]

else:

   print "ce dictionnaire n'a pas la valeur requise"

dico[cle]=valeur ajoute une valeur associée à une nouvelle clé à un dictionnaire ou modifie la valeur associée à cette clé.

dico.pop(clé) renvoie et supprime la valeur définie par une clé (ainsi que la clé)

dico.clear() supprime tous les éléments du dictionnaire dic

dico=dic.copy() copie un dictionnaire dans un autre, les modifications de l'un n'affectent pas l'autre

dico.keys() crée une liste des clés du dictionnaire dico

dico.values() crée une liste des valeurs du dictionnaire dico

Exercice

Écrire un programme qui permette d'associer sous forme de dictionnaire le tableau suivant :

Code

Nom

A

Adenine

C

Cytosine

G

Guanine

T

Thymine

Modifier ce programme pour qu'il puisse convertir l'affichage d'une séquence ADN.

>>> decode('ACTGA')'

Adenine-Cytosine-Guanine-Thymine'

Application au code génétique

  • Les biologistes explorent les données biologiques et essayent d'imaginer comment les utiliser en se basant sur leur structure effective au sein des systèmes vivants. La bioinformatique est souvent utilisée pour modéliser cette structure aussi finement que possible.

  • Les bioinformaticiens suivent parfois une approche légèrement différente de celle des biologistes. Ils partent de ce qu'ils veulent faire des données et essayent de les organiser pour atteindre ce but : ils essayent de trouver un algorithme en représentant les données dans une structure de donnée appropriée.

  • Maintenant que vous connaissez des structures de données différentes, examinons ces sujets étroitement liés que sont les algorithmes et les structures de données.

  • Des algorithmes différents nécessitent souvent des structures de données différentes.

Cas étude : base de données d'expression de gènes

  • Un organisme = 30000 gènes au total (ex : génome humain)

  • Examinons un type de cellule qui n'a jamais été correctement caractérisé dans certaines conditions environnementales intéressantes, et déterminons pour chaque gène s'il est exprimé ou non (ie. transcrit en ARN)

  • Nons disposons de puces à ADN qui nous ont donné les informations d'expression pour cette cellule

  • Nous devons rechercher pour chacun des gènes s'il est exprimé par la cellule

  • Nous souhaiterons inclure cette fonctionnalité de recherche sur un site web

  • Il y a plusieurs façons de procéder. Voyons dans un premier temps la nature des données à notre disposition. Imaginons que nous ayons le nom de tous les gènes de l'organisme associé à un nombre indiquant le niveau d'expression, les gènes non exprimés ont pour valeur 0

Solution 1 : Utiliser des listes non triées

  • Supposons que nous souhaitons voir si les gènes ont été exprimé sans se préoccuper du niveau. Utilisons les listes, structure que nous connaissons.

  • Rassemblons dans une liste le nom des gènes exprimés et écartons les autres. Ex : 8000 gènes exprimés. Pour chaque requête il faudra comparer avec les 8000 gènes jusqu'à les trouver. On peut parcourir tout le tableau sans trouver.

  • Ca fonctionne mais c'est très lent. En moyenne pour un gêne :

    • 1 requête de gène exprimé = examen de 4000 gènes,

    • 1 gène non exprimé = 8000 requêtes.

  • Si le gène est manquant on ne pourra répondre que par la négative, et non un message indiquant que le gène cherché ne fait pas parti de notre expérience.

Solution 2 : Utiliser des listes triées

Etant donné une liste triée et un élément ;

tant que (élément non trouvé ou plus d'éléments dans la liste) faire

  prenons le milieu de la liste

  comparons notre élément avec l'élément du milieu

  si (ils sont égaux)

  alors

    nous avons gagné

  sinon 

    ignorons la moitié du tableau à laquelle notre élément n'appartient pas

  fin Tant que

Il s'agit de la recherche dichotomique que vous allez aborder au cours suivant.

En Python les opérateurs de comparaison entre chaîne de caractères existent et sont définis selon l'ordre alphabétique.

>>> a="aze"

>>> b="azf"

>>> a == b

False

>>> a < b

True

>>> a > b

False

Pour trier une liste de chaînes de caractères, on peut donc utiliser au choix :

  • liste.sort()

  • sorted(liste)

Solution 3 : Utiliser un dictionnaire

Construire un hachage :

  • clés = nom des gènes,

  • valeur = niveau d'expression.

Savoir si un gène recherché est dans votre ensemble de données :

if nom_dico.has_key('ma_clé' ]): ...

Si vous voulez trier les éléments stockés :

cles = mon_dico.keys()

cles_tries = cles.sort()

Ça peut être long pour un tableau de taille importante !

En résumé

  • Un dictionnaire sera adapté si vous devez uniquement vérifier la présence d'un élément dans un ensemble qu'il n'est pas nécessaire de trier.

  • Une liste triée, associée à un algorithme de recherche binaire, est adaptée si vous avez besoin d'un ensemble ordonné et d'un accès relativement rapide et que vous n'avez pas besoin d'ajouter et supprimer des éléments fréquemment.

  • Une liste ou un dictionnaire ordonné sera adapté si les éléments n'ont pas besoin d'être ordonné mais que vous devez ajouter des éléments. Ceci est particulièrement utile pour exprimer le « plus vieil » élément (celui qui est dans la liste depuis longtemps).

AccueilProgrammation en Python > Dictionnaires et codes génétiques< PrécédentSuivant >