Bonjour,
Concernant les dates: je t'ai dit que, avec les dates inversées type "19660627", l'ordre chronologique coïncidait avec l'ordre alphabétique.
Cela veut dire que dans les comparaisons entre les dates inversées, on peut dire:
"19500626" < "19600627" est vrai dans la comparaison alphabétique, et cela coïncide avec le fait que "26/06/1950" est une date ANTERIEURE à "27/06/1960"
aussi facilement que "ARTHUR" < "JAMES" est vrai puisque "A" est AVANT "J" dans l'alphabet
A part ça, n’essaie pas de tout faire en même temps. Pense au "discours de la méthode" de Descartes => quand c'est compliqué: on décompose et on avance pas à pas! Donc, on tri d'abord, on inverse ensuite et on retire l'élément en trop 'H' enfin.
Reprends le code initial:
1 2 3 4 5 6 7 8
| def triInsertion(L):
for i in range(1, len(L)):
if L[i] < L[i-1]:
for k in range(0, i):
if L[i] < L[k]:
X = L.pop(i)
L.insert(k, X)
break |
Il n'y a que 2 lignes qui font des comparaisons: lignes 3 et 5. Il faut changer ces 2 comparaisons pour adapter l'algorithme à notre problème.
Il ne faut pas changer le sens des comparaisons, sinon, il faut recréer l'algorithme et tu perds du temps inutilement.
Si les dates sont déjà données en version inversées, c'est très simple:
le ligne 3 devient: if L[i][3] < L[i-1][3]:
et la ligne 5 (tu l'avais oubliée dans ta réponse précédente) devient: if L[i][3] < L[k][3]:
C'est aussi simple que ça!
Application:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| def triInsertion3LL(L):
for i in range(1, len(L)):
if L[i][3] < L[i-1][3]:
for k in range(0, i):
if L[i][3] < L[k][3]:
X = L.pop(i)
L.insert(k, X)
break
liste = [['MOPAL', 'ARTHUR', 'H', '19660627'], ['WILSON', 'MIKE', 'H', '19500626'], ['EMERIC', 'JAMES', 'H', '19600627']]
triInsertion3LL(liste)
print(liste) |
Ce qui affiche:
[['WILSON', 'MIKE', 'H', '19500626'], ['EMERIC', 'JAMES', 'H', '19600627'], ['MOPAL', 'ARTHUR', 'H', '19660627']]
On a bien les dates dans l'ordre chronologique '19500626' < '19600627' < '19660627'
On veut ensuite des dates dans l'autre sens: il faut inverser la liste:
1 2
| liste.reverse()
print(liste) |
Ce qui affiche:
[['MOPAL', 'ARTHUR', 'H', '19660627'], ['EMERIC', 'JAMES', 'H', '19600627'], ['WILSON', 'MIKE', 'H', '19500626']]
On veut suite supprimer le 'H':
1 2 3 4
| for sl in liste:
sl.pop(2)
print(liste) |
Ce qui affiche:
[['MOPAL', 'ARTHUR', '19660627'], ['EMERIC', 'JAMES', '19600627'], ['WILSON', 'MIKE', '19500626']]
Ce qui est, si j'ai bien compris, le résultat attendu.
Si par contre tu parts d'une date "normale" type '27/06/1966', tu peux créer une petite fonction utilitaire:
1 2
| def invdate(date):
return date[6:11] + date[3:5] + date[0:2] |
Et dans ce cas, les 2 lignes de comparaison de la fonction de tri doivent être corrigées:
ligne 3 => if invdate(L[i][3]) < invdate(L[i-1][3]):
ligne 5 => if invdate(L[i][3]) < invdate(L[k][3]):
Cela ne changera pas les 2 étapes suivantes (inversion de la liste et élimination du 'H'), et tu trouveras à la fin:
[['MOPAL', 'ARTHUR', '27/06/1966'], ['EMERIC', 'JAMES', '27/06/1960'], ['WILSON', 'MIKE', '26/06/1950']]
Ok?
Petit complément.
Au début tu ne voulais pas utiliser la méthode .sort() avec l'argument key=lamda... Mais la solution que je t'ai proposée plus haut a un inconvénient: si tu veux trier selon les prénoms, par exemple, tu es obligé de corriger la fonction de tri: c'est dommage!
On peut faire autrement. Voilà comment:
1 2 3 4 5 6 7 8 9 10
| def triInsertion(L, key=None):
if key==None:
key = lambda v: v
for i in range(1, len(L)):
if key(L[i]) < key(L[i-1]):
for k in range(0, i):
if key(L[i]) < key(L[k]):
X = L.pop(i)
L.insert(k, X)
break |
Avec cette fonction, si on ne donne pas de valeur à key (donc, key==None), on trie en comparant simplement les éléments de la liste (ici les sous-listes). Mais on peut modifier key à l'appel de la fonction, en disant qu'au lieu de comparer un élément 'v', on compare 'v[3]':
Cela donnera avec ton exemple:
1 2 3 4 5
| liste = [['MOPAL', 'ARTHUR', 'H', '19660627'], ['WILSON', 'MIKE', 'H', '19500626'], ['EMERIC', 'JAMES', 'H', '19600627']]
triInsertion(liste, key=lambda v: v[3])
print(liste) |
Ce qui affichera bien la liste triée selon les dates:
[['WILSON', 'MIKE', 'H', '19500626'], ['EMERIC', 'JAMES', 'H', '19600627'], ['MOPAL', 'ARTHUR', 'H', '19660627']]
Et si tu as les dates en format normal type '27/06/1960', il faut intégrer, bien sûr, la petite fonction utilitaire d'inversion des dates 'invdate' dans key:
triInsertion(liste, key=lambda v: invdate(v[3])
J'espère qu'avec tout ça, tu n'as pas seulement résolu ton problème: tu as appris quelque chose que tu pourras reproduire...
Partager