Python propose trois méthodes principales pour trier des données:
- L'instruction sorted
- La méthode sort pour les conteneurs (list, tuple) .
- La méthode __lt__ à implémenter
L'instruction native 'sorted' qui permet de trier n'importe quelle collection à partir du moment où elle est:
- Homogène: les éléments sont de même nature.
- Itérable : elle peut délivrer les données les unes après les autres.
- Il existe un dispositif connu de comparaison des données deux à deux
Démonstration:
Pour pallier aux différents cas de figure, l'instruction sorted introduit un paramètre supplémentaire: 'key' qui permet d appliquer une fonction appelée au moment du classement des données.
ici on peut ajouter: key=str qui va transformer chaque item en string (sans impact pour un item déjà de cette classe)
La solution la plus souple est d'utiliser une fonction lambda pour réaliser des personnalisations de tri complexes: exemple pour faire passer les lettres avant les chiffres.
(le symbole '|' a un code ascii inférieur à 'a') Ici on ajoute '|' avant le resultat de la fonction 'str'.
Enfin, il est possible d'implémenter la méthode __lt__ d'un objet.
exemple ici où une classe implémente la méthode 'lt' basée sur l'identifiant des objets.
La prise en charge des tris ressemble au dernier exemple.
Le package 'sort' apporte des utilitaires pour trier la plupart des types de base.
Il s'utilise en l'état pour des tris basiques :
a := []int{3, 6, 4, 1}
fmt.Println("avant", a)
sort.Ints(a)
fmt.Println("après", a)
avant [3 6 4 1]
après [1 3 4 6]
Si on reprend les exemples des autres posts:
avec un dé pipé:
type DePipe struct {
De
Faceplus int
}
Après une série de tirage , on obtient
face: 1 score: 16.00
face: 2 score: 14.20
face: 3 score: 15.50
face: 4 score: 13.60
face: 5 score: 13.60
face: 6 score: 27.10
Pour trier sur la fréquence, on utilisera SliceStable du package sort.
sort.SliceStable(tface, func(i, j int) bool { return tirages2[tface[i]] < tirages2[tface[j]] })
Si on souhaite quelle chose de plus souple, par exemple pour trier un tableau avec de nombres et des chaines. On peut définir un tableau acceptant tous les types et implémenter les fonctions de l'interface sort:(len , swap, less)
type Maliste []interface{}
func (a Maliste) Len() int { return len(a) }
func (a Maliste) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
func (a Maliste) Less(i, j int) bool {
si := fmt.Sprintf("%v", a[i])
sj := fmt.Sprintf("%v", a[j])
if _, ok := a[i].(int); ok {
si = fmt.Sprintf("|%v", a[i])
}
if _, ok := a[j].(int); ok {
sj = fmt.Sprintf("|%v", a[j])
}
return si < sj
}
Utilisation:
g := Maliste{3, 6, "a", 4, 1}
fmt.Printf("g avant tri: %T, %v\n", g, g)
sort.Sort(g)
fmt.Printf("g apres tri: %T, %v\n", g, g)
Ici dans la fonction less , comme dans l'exemple Python , j'ajoute un caractère dans un entier afin de faire passer les lettres avant les chiffres. Avec comme résultat:
g avant tri: main.Maliste, [3 6 a 4 1]
g apres tri: main.Maliste, [a 1 3 4 6]
Inverser l'ordre d'un tri.
En Python, l'option reverse permet de sélectionner l'ordre descendant:
Exemple:
sort.Sort(sort.Reverse(g))
g apres tri: main.Maliste, [a 1 3 4 6]
g apres inversion tri: main.Maliste, [6 4 3 1 a]
Voila pour les opérations basiques de tri.
Aucun commentaire:
Enregistrer un commentaire