Inscription / Connexion Nouveau Sujet
Niveau Maths sup
Partager :

Python

Posté par
Rira
03-08-19 à 17:50

bonjours,
Ecrire une fonction: Fréquences(L), qui reçoit en paramètre une liste d'entier L, et qui retourne une liste de tuples: Chaque tuple est composé d'un élément de L et de son occurrence dans L. Les premiers éléments des tuples de la liste des fréquences doivent être tous différents (sans doublant).
exemple: L=[12,4,5,12,4,4,2,5]
La fonction fréquences(L) retourne la liste F=[(2,1),(4,3),(5,2),(12,2)]
Voici mon programme:
def rep(L):
    for e in L:
        if L.count(e)>1:
            L.remove(e)
    return L        
    

def fréquences(L):
    F=[]
    for i in range (0,len(L)):
        F.append((L[i],L.count(L[i])))
    return sorted(rep(F))
Mais ça marche pas
par exemple pour le même exemple au lieu du résultat , ça me donne    [(2, 1), (4, 3), (4, 3), (5, 2), (12, 2)]
De l'aide s'il vous plait et merci d'avance.

Posté par
Jezebeth
re : Python 03-08-19 à 17:55

Bonjour

Je ne lirai pas vos programmes si vous ne les commentez pas, pas assez de temps à perdre...

pour programmer ce qui est demandé :
- écrire une fonction qui pour un élément e de la liste L, renvoie son nombre d'occurrences dans L
- écrire une fonction qui prend L, qui construit une nouvelle liste parcourant L : pour chaque élément rencontré, utiliser la première fonction pour récupérer le tuple à insérer dans la nouvelle liste, puis supprimer toutes ses occurrences dans L.

Posté par
Rira
re : Python 03-08-19 à 18:07

Jezebeth
ça fait trop de fonctions , et j'aimerai bien si possible de savoir l'erreur dans mon programme. Déjà j'ai utiliser deux fonction, la première qui élimine les doublons dans une liste est juste .
Ce qui me gène dans mon programme est qu'il marche pour certain exemple et non pour d'autre
par exemple pour  L=[12,5,12,4,4,2,5,6,5] j'obtient F=[(2, 1), (4, 2), (5, 3), (6, 1), (12, 2)]
le résultats désiré mais pour l'exemple que j'ai cité avant ça ne marche pas

Rira @ 03-08-2019 à 17:50

  [(2, 1), (4, 3), (4, 3), (5, 2), (12, 2)]
il y a (4,3) qui se répète deux fois

Posté par
flight
re : Python 03-08-19 à 18:14

salut

qu'appelles tu "Chaque tuple est composé d'un élément de L et de son occurrence dans L."?   precisement que doit on comprendre par l'occurence de l'element choisit?

Posté par
Rira
re : Python 03-08-19 à 18:17

flight
chaque tuple est composé d'un élément de L et le nombre de fois cet élément est répété dans L

Posté par
Jezebeth
re : Python 03-08-19 à 18:31

Rira, quand tu ne m'expliques pas l'idée derrière ton programme et que tu ne le commentes pas un minimum je ne jetterai pas un œil
d'autant que je n'ai que ma tête et pas de compilateur pour tester et te dire précisément ce qui ne va pas

et y a jamais trop de fonctions !
programmer des fonctions auxiliaires c'est la base des bases

Posté par
Rira
re : Python 03-08-19 à 18:39

Jezebeth
J'ai essayé d'expliquer dans mon deuxième message.
je voudrai juste savoir pourquoi un élément se répète plus qu'une fois même après avoir utiliser la fonction qui élimine les doublons .

Posté par
Rira
re : Python 03-08-19 à 18:44

Rira @ 03-08-2019 à 17:50


            
    
J'obtiens le résultat lorsque je réécris la fonction rep deux fois  
def fréquences(L):
    F=[]
    for i in range (0,len(L)):
        F.append((L[i],L.count(L[i])))
    return sorted(rep(rep(F)))
.

Posté par
lg124
re : Python 03-08-19 à 22:13

Bonjour,

1) On évite de modifier la taille d'une liste sur laquelle on itère.

2) Pourquoi ne pas utiliser une structure de donnée qui est sans doublons? par exemple un dictionnaire.

3) Ton algorithme est très inefficace (quadratique),  un seul parcours de la liste est nécessaire pour faire ce que tu veux.

4) Quel est le cadre de l'exercice? En python il y a la classe Counter qui fait précisément ce que tu veux.


>>> from collections import Counter
>>> L=[12,4,5,12,4,4,2,5] 
>>> print(sorted(Counter(L).items()))
[(2, 1), (4, 3), (5, 2), (12, 2)]

Posté par
flight
re : Python 03-08-19 à 22:38

salut

voici un essai sur excel vba , a adapter dans le langage que tu connais :

Sub occurence()
Dim v As Variant
v = Array(12, 4, 5, 12, 4, 4, 2, 5)

For k = Application.Min(v) To Application.Max(v)
n = 0
   For j = 0 To UBound(v)
      If k = v(j) Then
        n = n + 1
      End If
   Next j
   If n <> 0 Then
      cumul = cumul & Chr(10) & "( " & k & "," & n & ")"
   End If
Next
msgbox cumul

End Sub

ce qui me retourne (2,1) (4,3) (5,2) (12,2)

Posté par
carpediem
re : Python 03-08-19 à 23:20

salut

lg124 : certes ... mais justement le but de l'exercice est de programmer cette fonction counter !!!

j"aurai tout simplement fait :

def  moi (L)
  M = []
  for a in L and not in M
     M.append ((a, L.count(a)))
return sorted(M)


veuiller me pardonner pour l'éventuelle mauvaise syntaxe ... ne connaissant que très peu python ...

Posté par
Rira
re : Python 04-08-19 à 03:41

lg124
Il est écrit qu'on ne doit pas utiliser la fonction counter

Posté par
Rira
re : Python 04-08-19 à 03:43

carpediem
Le problème c'est que lorsqu'il y a un a qui se répète plus qu'une seule fois , on le trouve repéré dans la liste obtenue M

Posté par
perroquet
re : Python 04-08-19 à 06:36

Bonjour, Rira.

Tu te demandes pourquoi ton programme ne fonctionne pas ...

En fait, c'est ta fonction "rep" qui est fautive. Tu pourras vérifier qu'elle ne donne pas le bon résultat lorsque  L=[1,1,1,1,1,1] ou L=[1,2,3,2,3,1]. Si on applique deux fois la fonction "rep" aux exemples que j'ai donnés, on éliminera tous les doublons. Mais il existe des exemples où on n'éliminera pas tous les doublons en appliquant deux fois la fonction "rep".

Pourquoi ta fonction ne donne-t-elle pas le résultat attendu ?
lg124 te l'a expliqué, c'est parce que tu modifies la liste sur laquelle tu itères.
Détaillons ce qui se passe dans l'exemple   L=[1,2,3,2,3,1].
A la première étape, tout se passe bien: on examine le premier élément de la liste, qui est 1. Il y a un doublon, donc, on supprime cet élément et la nouvelle liste L devient [2,3,2,3,1].
Mais à la deuxième étape, on examine le deuxième élément de la nouvelle liste L (qui n'est pas le deuxième élément de l'ancienne liste L). On examine l'élément "3" et pas l'élément "2". Une nouvelle fois, il y a un doublon, on supprime 3, et la nouvelle liste L devient [2,2,3,1].
On examine ensuite le troisième et le quatrième élément de L, il n'y a plus de doublon...
Et voilà comment au cours de l'exécution de la fonction, on n'a jamais examiné les deux éléments "2".

Comment résoudre le problème:
Il faut réécrire la fonction "rep". Par exemple, au lieu de retirer l'élément qu'on examine, on peut retirer les autres doublons (ceux qui suivent). Mais, comme l'a écrit lg124, il est fortement déconseillé de modifier une liste sur laquelle on itère.
Voici ma version de la fonction "rep".
def rep2(L):
    G=[]
    for i in L:
        if not(i in G):
            G.append(i)
    return G

Ceci dit:
Comme d'autres intervenants l'ont signalé, la méthode utilisée n'est pas du tout efficace. Mais ta demande portait sur la correction de ton programme.

Posté par
carpediem
re : Python 04-08-19 à 12:55

Rira @ 04-08-2019 à 03:43

carpediem
Le problème c'est que lorsqu'il y a un a qui se répète plus qu'une seule fois , on le trouve repéré dans la liste obtenue M
ben non :
carpediem @ 03-08-2019 à 23:20

def  moi (L)
  M = []
  for a in L and not (a in M)
     M.append ((a, L.count(a)))
return sorted(M)
je ne rajoute a à la liste M que s'il n'y appartient pas encore ...

PS : j'ai légèrement modifié pour respecter la syntaxe (en copiant sur perroquet que je remercie)

Posté par
Rira
re : Python 04-08-19 à 21:39

carpediem
Lorsque je vérifie le programme ça me donne le message suivant:
    for a in L and not a in F:
UnboundLocalError: local variable 'a' referenced before assignment

Posté par
Rira
re : Python 04-08-19 à 21:50

perroquet
Je pensait que lorsque j'écris for e in L par exemple, à chaque fois e parcourt tous les éléments de L. Ce qui n'est pas le cas apparemment. C'est ça??

Posté par
Rira
re : Python 04-08-19 à 21:58

perroquet
Et pour votre version de la fonction fréquence , il y toujours le problème des éléments répétés .

Posté par
perroquet
re : Python 04-08-19 à 23:44

@Rira

Citation :

Je pensait que lorsque j'écris for e in L par exemple, à chaque fois e parcourt tous les éléments de L. Ce qui n'est pas le cas apparemment. C'est ça??


Réponse:
Si la liste L n'est pas modifiée pendant l'exécution de la boucle for, e parcourt tous les éléments de L.
Par contre, si la liste L est modifiée pendant l'exécution, e peut ne pas parcourir tous les éléments de la liste initiale L. C'est ce que j'ai expliqué dans mon post précédent.

Citation :

Et pour votre version de la fonction fréquence , il y toujours le problème des éléments répétés .


Réponse:
Bien évidemment, j'ai testé ton programme et j'ai constaté qu'il ne donnait pas le bon résultat pour  L=[12,4,5,12,4,4,2,5]. Ensuite, après quelques tests, j'ai compris pourquoi il ne fonctionnait pas pour cet exemple.
J'ai aussi testé la modification de programme que je proposais et j'ai constaté qu'il donnait le bon résultat pour L=[12,4,5,12,4,4,2,5].
Je suis donc très étonné ...
Voici une copie de mon programme.

def rep2(L):
    G=[]
    for i in L:
        if not(i in G):
            G.append(i)
    return G

def frequences(L):
    F=[]
    for i in range(0,len(L)):
        F.append((L[i],L.count(L[i])))
    return sorted(rep2(F))  

Posté par
carpediem
re : Python 04-08-19 à 23:47

ok alors je vois !!

def  moi (L)
  M = []
  for a in L
     if not (a in M)
         M.append ((a, L.count(a)))
return sorted(M)


devrait maintenant marcher ...

Posté par
Rira
re : Python 04-08-19 à 23:56

perroquet
Ah oui ça marche. Merci infiniment pour votre temps et vos explications bien détaillées .

Posté par
Rira
re : Python 04-08-19 à 23:58

carpediem
Je ne sais pas où est le problème, mais il y a toujours le problème des éléments répétés, même avec la condition if not (a in M)

Posté par
carpediem
re : Python 05-08-19 à 00:07

évidemment !!! que je suis bête !!!

M est une liste de tuple !!!

def  moi (L)
  M = []
  for a in L
    x = (a, L.count(a))
    if not (x in M)
       M.append (x)
return sorted(M)

Posté par
perroquet
re : Python 05-08-19 à 00:33

Bonjour, carpediem.

Voici une version "python-syntaxiquement-correcte" de ton idée (note à l'intention de Rira: j'ai testé sur ton exemple et ça marche).

def moi(L):
    M=[]
    N=[]
    for a in L:
        if not(a in N):
            M.append((a, L.count(a)))
            N.append(a)
    return sorted(M)

J'ai créé une deuxième liste d'entiers N, parce que M est une liste de tuples et on ne peut donc pas tester l'appartenance de a à M ...

Cela donne un algorithme en maximum O(n2) opérations élémentaires (où n est la taille de la liste), mais il peut être beaucoup plus efficace dans certains cas (par exemple une liste ne comportant que des 1).

On peut écrire un algorithme en O(n\ln(n)) en commençant par trier la liste L mais cet algorithme pourra se révéler moins performant que le précédent dans certains cas.

Posté par
Rira
re : Python 05-08-19 à 00:40

carpediemperroquet
Merci beaucoup pour votre temps.

Posté par
perroquet
re : Python 05-08-19 à 01:03

@carpediem:

Je n'avais pas lu tes interventions à partir de 23h47.
Donc, ce que j'ai écrit à 0h33 n'a plus grand intérêt.

Pour que mon compilateur accepte le programme que tu as écrit, il manque un petit peu de ponctuation (':' à la fin des lignes 1,3,5). Et l'indentation de la dernière ligne est fautive. Ce qui donne le programme suivant

def  moi (L):
  M = []
  for a in L:
    x = (a, L.count(a))
    if not (x in M):
       M.append (x)
  return sorted(M)

je ne comprends pas pourquoi les indentations diffèrent et pourquoi elles reprennent le format de carpediem quand je refais un "copier-coller" de la version ci-dessus dans ma console python

J'ai testé sur l'exemple de Rira, ça marche.

Posté par
carpediem
re : Python 05-08-19 à 09:13

merci beaucoup perroquet !!

je "débute" en python et effectivement j'oublie toujours la ponctuation en ne pensant qu'à la seule indentation

quant au "coût" de cet algo ce n'est effectivement pas ce que j'ai regardé en premier : j'ai fait au plus naturel : prendre tout élément de la liste L tant qu'il n'est pas dans la liste M ... encore fallait-il considérer les "bons" (types d') éléments ... mais cela peut effectivement jouer pour des très grandes listes ...

encore merci



Vous devez être membre accéder à ce service...

Pas encore inscrit ?

1 compte par personne, multi-compte interdit !

Ou identifiez-vous :


Rester sur la page

Inscription gratuite

Fiches en rapport

parmi 1675 fiches de maths

Désolé, votre version d'Internet Explorer est plus que périmée ! Merci de le mettre à jour ou de télécharger Firefox ou Google Chrome pour utiliser le site. Votre ordinateur vous remerciera !