Listes

Rangs impairs.

Écrire une fonction python prenant en paramètre une liste et affichant les éléments d'indices impairs de cette liste.


def afficheRangsImpairs(liste) :
	for j in range(1, len(liste), 2) :
		print("Elément d'indice {} : {}".format(j, liste[j]))
		
		
# essai sur la liste des carrés des premiers entiers :
L=[ k**2 for k in range(20)]
afficheRangsImpairs(L)

Max d'une liste.

L étant une liste de nombres, le code python max(L) renvoie la valeur maximale contenue dans la liste.

Écrire une fonction python prenant en paramètre une liste de nombres et renvoyant la valeur maximale des éléments de la liste.

En d'autres termes, il s'agit d'écrire votre propre version de la fonction python max() (vous n'avez donc pas le droit de vous en servir !)


from random import randint 

def maxliste(liste) :
	m=liste[0]
	for x in liste :
		if x>m : m=x
	return m

# liste de longueur 10 d'entiers au hasard entre 1 et 100 :
L = [ randint(1,100) for j in range(10) ]

print(L) # affichage de la liste
print(maxliste(L)) # affichage de l'élément max de la liste

print(max(L)) # utilisation de la fonction prédéfinie python pour vérif

Insertion dans une liste.

L étant une liste de nombres, le code python L.insert(position, element) insère l'élément 'element' en position 'position' dans la liste (exemples dans le cours).

Écrire une fonction python ayant le même effet. On n'aura donc pas le droit de se servir de la méthode python insert(). On pourra, si besoin, utiliser la méthode append().


def insere(liste, position, element) :
	""" insere element dans liste à l'indice position."""
	liste.append(0) # création d'un emplacement 
					# supplémentaire en fin de liste
	for k in range(len(liste)-1, position ,-1) :
		liste[k]=liste[k-1] # décalage des éléments vers la droite
	liste[position]=element 
	

# essai
# pensez à tester les positions extrêmes pour votre fonction :
# indice 0, indice len(L)-1, indice len(L)
L=[ j for j in range(10)]
print(" Liste avant modification : {}.".format(L))
insere(L, 3 , 100)
print(" Liste après modification : {}.".format(L))

Réécriture des méthodes des listes.

Les fonctions append, insert, extend, pop et remove s'appellent comme des suffixes d'une liste et la modifient directement - on parle de méthodes des objets listes.

Écrire les fonctions monappend, moninsert, monextend, monpop et monremove qui miment leurs effet mais renvoient une nouvelle liste, sans modifier la liste de départ L. Ainsi :

  • L = monextend(L,M) agit comme L.extend(M) (mais A = monextend(L,M) ne modifie pas L).
  • L = monappend(L,elt) agit comme L.append(elt)
  • monremove(L, elt) renvoie une liste où tous les éléments elt ont été retiré, et une copie de L s'il n'y en a pas.
  • (L,a) = monpop(L,pos) agit comme a = L.pop(pos)
  • L = moninsert(L, pos, elt) agit comme L.insert(pos, elt)

On ne se préoccupera pas des difficultés posées par la gestion des listes de listes.


def monextend(L,M):
    return (L+M)

def monappend(L,elt):
    return (L+[elt])

def monremove(L,elt):
    res = []
    for e in L:
        if e != elt:
            res = res + [e]
    return res

def monpop(L, pos):
    res = []
    for i in range(len(L)):
        if i != pos:
            res = res + [L[i]]
    return (res,L[pos])

def moninsert(L,pos,elt):
    if pos == len(L):
        return monappend(L,elt)
    else:
        res = []
        for i,e in enumerate(L):
            if i == pos:
                res = res + [elt] + [e]
            else:
                res= res + [e]
        return res

Journée pancake.

On considère le programme suivant :


import random as rd

def retourne(L,n) :
	""" retourne l'ordre des éléments en queue de liste L
	à partir de l'élément d'indice n."""
	queue = L[n:]
	queue.reverse()	 
	return L[:n] + queue
	

def plusGrand(L,n) :
	""" retourne le rang du plus grand élément 
	de la queue de liste L (queue considérée à partir de 
	l'élément d'indice n)."""
	 
	return L.index( max(L[n:]),n )	



def mystere(L) :
	for i in range(len(L)) :
		k = plusGrand(L,i)
		L = retourne(L,k)
		L = retourne(L, i)

	return L
	

 
 
L = [ rd.randint(0,100) for i in range(20) ]
 
L = mystere(L)
print(L)

Sans le tester, devinez l'effet sur les listes L testées.

Si vous ne trouvez pas, testez et essayez de comprendre le fonctionnement.

.

Le programme trie la liste en ordre décroissant.

Pour comprendre son principe, cherchez sur le web avec les mots clefs "pancake sorting" ou encore "tri de crêpes".

Tri d'une liste.

L'exercice précédent a montré un exemple de programme permettant de trier une liste.

De façon générale, le tri est important en informatique.

Il existe bien entendu des fonctions prédéfinies en python qui permettent de trier efficacement une liste.

Vérifier par exemple que L est triée dans le second affichage ci-dessous :


L = [ 2, 5, 1, 8, 2, 9 , -5 ]
print(L)
L.sort()
print(L)

Votre mission est maintenant d'écrire une fonction de tri d'une liste. Interdiction évidemment de se servir de la méthode sort() prédéfinie ! Et le principe utilisé devra être différent du principe du pancake sorting de l'exercice précédent.

.

Il existe de nombreux algorithmes de tris, plus ou moins efficaces suivant les situations.

Vous pourrez trouver sur le web le principe d'un certain nombre d'algorithmes de tri en entrant sur un moteur de recherche des expressions comme tri rapide (quick sort), tri fusion (merge sort), tri par sélection...

Si vous n'êtes pas parvenu à écrire un porgramme de tri en python, chercher "algorithme de tri" et "python" dans un moteur de recherche. Vous obtiendrez bon nombre de programmes python répondant à la question. Par exemple, sur cette page.

Mélanger un paquet de cartes.

Dans cet exercice, on va chercher à mélanger les éléments d'une liste.

  1. Commencer par définir une liste vide nommée paquet (représentant un paquet de cartes).
  2. Écrire une fonction python remplir prenant en entrée une liste et un nombre n et ayant pour effet d'initialiser la liste avec les entiers 1, 2, 3, ..., n (dans cet ordre).
    Exemple : dans le programme, après l'appel remplir(paquet, 5), paquet sera égal à [1,2,3,4,5].
  3. Écrire une fonction python afficher qui prend en paramètres une liste et un entier n et qui affiche les éléments de la liste, à raison de n éléments par ligne.
    L'utilisateur doit pouvoir ne pas préciser de valeur pour n, n prendra dans ce cas la valeur 6 par défaut.
  4. Écrire une fonction python echanger prenant en paramètres une liste et deux indices d'éléments de la liste et qui a pour effet d'échanger les contenus de ces deux éléments.
    Exemple : si paquet = [1,2,3,4,5,6,7], après l'appel echanger(paquet,2,5), paquet sera égal à la liste [1,2, 6, 4,5, 3, 7].
  5. Écrire une fonction inverser prenant en paramètres une liste et deux indices i et j (i < j) d'éléments de la liste et qui a pour effet d'inverser l'ordre des éléments de la liste, d'indices entre i et j.
    Exemple : si la liste est paquet = [1,2,3,4,5,6,7,8], alors après l'appel inverser(paquet, 3,6), paquet sera égal à la liste [1,2,3,7,6,5,4, 8].
  6. Écrire une fonction circulaire_gauche qui prend en paramètre une liste et a pour effet de faire subir une permutation circulaire gauche de un rang aux éléments de la liste, c'est à dire de décaler d'un rang vers la gauche tout élément de la liste, le premier élément passant en queue de liste.
    Exemple : si paquet = [1,2,3,4], après l'appel circulaire_gauche(paquet), paquet est égal à la liste [2,3,4,1].
  7. Écrire une fonction circulaire_gauche_n qui prend en paramètres une liste et un entier naturel n et a pour effet de faire une parmutation circulaire gauche de n rangs aux éléments de la liste, c'est à dire de décaler de n rangs vers la gauche tout élément de la liste.
  8. On utilise maintenant les fonctions précédentes pour mélanger le paquet. Pour cela, on va choisir au hasard les opérations suivantes :
    • Opération 1 : on échange les contenus de deux cases différentes de paquet, cases choisies au hasard.
    • Opération 2 : on choisit un entier n au hasard ( \( 1 < n \leqslant \text{longueur de la liste} \) ) et on fait subir une permutation circulaire de n cases à notre liste paquet.
    • Opération 3 : on inverse l'ordre des cartes de paquet entre l'indice m et l'indice m+n où n et m sont choisis au hasard (avec \( 2 \leqslant n < \text{longueur de la liste}//2 \) et \( 0 \leqslant m < \text{longueur de la liste}//2 \) )

    L'opération 1 sera choisie avec une probabilité de \( \frac{1}{6} \), l'opération 2 avec une probabilité de \( \frac{1}{3} \) et l'opération 3 avec une probabilité \( \frac{1}{2} \).

    L'ensemble (choix d'une opération au hasard et application de cette opération) sera répété autant de fois qu'il y a de cartes dans le paquet.

.


from random import randint

def remplir(tableau, nb_cases):
	for i in range(nb_cases) :
		tableau.append(i+1)
		

def afficher(tableau, nb_par_lignes = 6) :
	for i in range(len(tableau)-1) :
		print(tableau[i], end=", ")
		if (i+1)%nb_par_lignes == 0 : print()
	print(tableau[-1], end=".")
				
 	
	
def echanger(tableau, indice1, indice2) :
	tableau[indice1], tableau[indice2] = tableau[indice2], tableau[indice1] 
	
	
def inverser_de_n_a_m(tableau, rang1, rang2) :
	for i in range(rang1, (rang2+rang1)//2 + 1 ) :
		echanger(tableau, i, rang2+rang1-i )
	 
 
	
		
def permuter_gauche(tableau) :
	for i in range(len(tableau)-1) :
		echanger(tableau, i, i+1)
	


def permuter_gauche_n(tableau, n) :
	for _ in range(n) :
		permuter_gauche(tableau)


def melanger(tableau):
	
	for _ in range(len(tableau)) : 
		alea = randint(0,5)
		if alea == 0 :
			n = randint(0, len(tableau))
			m = randint(0, len(tableau))
			while m == n : m = randint(0, len(tableau))
			echanger(tableau, n, m)
		elif alea in (1,2) :
			n = randint(1, len(tableau)-1)
			permuter_gauche_n(tableau, n)
		else :
			n = randint(2, len(tableau)//2-1)
			m = randint(0, len(tableau)//2-1)
			inverser_de_n_a_m(tableau, m, m+n)





paquet = [] # paquet de cartes, vide au départ 



print("Remplissage initial :")
remplir(paquet, 19) # paquet de cartes numérotées de 1 à 19
afficher(paquet, 5)

 
 
print("\n\nEchange des éléments d'indice 2 et 5 :")
echanger(paquet, 2, 5) 
afficher(paquet)




print("\n\nInversion dun sous-paquet de cartes (indices de 3 à 6)  :")
inverser_de_n_a_m(paquet, 3, 6)
afficher(paquet)
 

print("\n\nPermutation gauche un rang  :")
permuter_gauche(paquet)
afficher(paquet)

print("\n\nPermutation gauche 3 rangs  :")
permuter_gauche_n(paquet,3)
afficher(paquet)



print("\n\nMélange : ")
melanger(paquet)
afficher(paquet,4)