IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Python Discussion :

map et round


Sujet :

Python

  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Août 2009
    Messages
    195
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Août 2009
    Messages : 195
    Par défaut map et round
    Bonjour,

    Ayant fait de courtes recherches sur le net et n'ayant pas trouvé, je me permets de vous solliciter.
    Sur python 2.5.1 environnement Windows Xp, je fais ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    >>>a=[1.0,2.0,3.0]
    >>>b=map(lambda f:f*100/sum(a),a)
    >>>print b
    [16.6666666666668, 33.3333333333336, 50.0]
    >>>c=map(lambda f:round(f,2),b)
    >>>print c
    [16.670000000000002, 33.3299999999998, 50.0]
    Bien entendu, je voudrais avoir [16,67, 33,33, 50.0]
    J'avais mis le round initialement dans le 1er map ce qui revient au même
    Avez vous une suggestion? J'ai pas envie de créer une fonction alors qu'il y a les outils pour, et surtout je voudrais comprendre pourquoi.

    Merci

    PS:

    Plus fort, je dois avoir les elements en chaine, je fais donc:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    >>>d=map(lambda f:str(f),c)
    >>>print d
    ['16.67', '33.33', '50.0']

  2. #2
    Membre Expert
    Homme Profil pro
    Inscrit en
    Avril 2004
    Messages
    1 067
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 1 067
    Par défaut
    vite fait; y a sûrement plus simple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    a=12.3568 
    str(round(a,2))[:str(round(a,2)).index('.')+3]

  3. #3
    Membre Expert
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 418
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 418
    Par défaut
    Bonjour,


    Pour comprendre ce qui se passe:
    http://www.python.org/doc/2.4.1/tut/node16.html


    Pour solutionner:
    http://docs.python.org/library/decim...module-decimal



    ##################################################
    Attention, ce qui suit est une ânerie commise par précipitation.
    Le correctif se trouve dans le message #5 qui suit dans cette file.
    -- Édité le 3 mars 10
    --



    Une chose aussi à savoir : le nombre de digits pris en compte par Python pour un nombre à virgule entré au clavier est limité.

    Quand je dis nombre de digits, c’est aussi bien avant qu’après la virgule (enfin, le point...)



    Dans IDLE, par exemple

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    print '12 digits',    12.0000000002
    print '12 digits',str(12.0000000002)
    print '13 digits',    12.00000000023
    print '13 digits',str(12.00000000023)
    print '13 digits',    12.00000000003
    print '13 digits',str(12.00000000003)
    print
    print '12 digits',    12.3456789012
    print '12 digits',str(12.3456789012)
    print '13 digits',    12.34567890123
    print '13 digits',str(12.34567890123)
    donne

    12 digits 12.0000000002
    12 digits 12.0000000002
    13 digits 12.0000000002
    13 digits 12.0000000002
    13 digits 12.0
    13 digits 12.0

    12 digits 12.3456789012
    12 digits 12.3456789012
    13 digits 12.3456789012
    13 digits 12.3456789012
    Le nombre de digits pris en compte est 12





    Idem en ligne de commande à cette différence près que le nombre de digits pris en compte y est 16 !

    ##################################################



    Il semble que ce soit en entrée pour la même raison qu’en sortie; cette raison ayant été donnée par rambc dans ce post

    http://www.developpez.net/forums/d86...e/#post4940719

    Il ne faut pas oublier que print appelle la méthode __str__ des objets de type float.
    Ici la méthode __str__ nettoie la représentation utilisée en interne du nombre 1.1.

    Plus précisément, on a :

    >>> str(0.1)
    '0.1'
    >>> repr(0.1)
    '0.10000000000000001'


    Dans la file en question, où j’ai d’ailleurs trouvé le premier lien, autres propos intéressants aussi.

  4. #4
    Membre confirmé
    Profil pro
    Inscrit en
    Août 2009
    Messages
    195
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Août 2009
    Messages : 195
    Par défaut
    Merci à Josmiley pour une solution brève et fonctionnelle.
    Et merci également à Eyquem pour les explications bien fournies!
    Ça permet de comprendre comment Python gère les digits et l'affichage

  5. #5
    Membre Expert
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 418
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 418
    Par défaut
    Sauf que j’ai raconté n’importe quoi dans la fin.



    Le code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    print '12 digits',    12.0000000002
    print '12 digits',str(12.0000000002)
    print '13 digits',    12.00000000023
    print '13 digits',str(12.00000000023)
    print '13 digits',    12.00000000003
    print '13 digits',str(12.00000000003)
    print
    print '12 digits',    12.3456789012
    print '12 digits',str(12.3456789012)
    print '13 digits',    12.34567890123
    print '13 digits',str(12.34567890123)
    ne montre absolument pas ce qui est pris en compte comme digits par Python en entrée, puisqu’il y a dans ces instructions des print !

    Ce code montre surtout ce qu’a expliqué rambc: en affichage, Python utilise str() et ça limite à 12 dans IDLE et à 16 en ligne de commande le nombre de digits pour l’affichage du résultat.







    Pour ce qui est du nombre de digits pris en considération par Python en entrée, peut être le code suivant permet-il de conclure quelque chose.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    x = 12.00000000000000001
    y = (x-12)*1000000000000000000000000000
    print 'x = 12.00000000000000001'
    print 'x a 19 digits, 17 decimales apres la virgule','y =',y
     
    x = 12.0000000000000001
    y = (x-12)*1000000000000000000000000000
    print 'x = 12.0000000000000001'
    print 'x a 18 digits, 16 decimales apres la virgule','y =',y
     
    x = 12.000000000000001
    y = (x-12)*1000000000000000000000000000
    print 'x = 12.000000000000001'
    print 'x a 17 digits, 15 decimales apres la virgule','y =',y
     
    x = 12.00000000000001
    y = (x-12)*1000000000000000000000000000
    print 'x = 12.00000000000001'
    print 'x a 16 digits, 14 decimales apres la virgule','y =',y
     
     
    print
    x = 2.000000000000000008
    y = (x-2)*100000000000000000000000000000000
    print '2.000000000000000008'
    print 'x a 19 digits, 18 decimales apres la virgule','y =',y
     
    x = 2.00000000000000007
    y = (x-2)*100000000000000000000000000000000
    print '2.00000000000000007'
    print 'x a 18 digits, 17 decimales apres la virgule','y =',y
     
    x = 2.0000000000000006
    y = (x-2)*100000000000000000000000000000000
    print '2.0000000000000006'
    print 'x a 17 digits, 16 decimales apres la virgule','y =',y
     
    x = 2.000000000000005
    y = (x-2)*100000000000000000000000000000000
    print '2.000000000000005'
    print 'x a 16 digits, 15 decimales apres la virgule','y =',y
    x = 12.00000000000000001
    x a 19 digits, 17 decimales apres la virgule y = 0.0
    x = 12.0000000000000001
    x a 18 digits, 16 decimales apres la virgule y = 0.0
    x = 12.000000000000001
    x a 17 digits, 15 decimales apres la virgule y = 1.7763568394e+12
    x = 12.00000000000001
    x a 16 digits, 14 decimales apres la virgule y = 1.06581410364e+13

    2.000000000000000008
    x a 19 digits, 18 decimales apres la virgule y = 0.0
    2.00000000000000007
    x a 18 digits, 17 decimales apres la virgule y = 0.0
    2.0000000000000006
    x a 17 digits, 16 decimales apres la virgule y = 4.4408920985e+16
    2.000000000000005
    x a 16 digits, 15 decimales apres la virgule y = 4.88498130835e+17
    Mais chat échaudé craint l’eau froide, et je ne m’y risque pas. Je vais potasser moi même les liens que je donne avant de raconter des âneries supplémentaires.

  6. #6
    Membre Expert
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 418
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 418
    Par défaut
    Avant que je connaisse la fonction repr() , quand je voulais examiner précisément les caractères présents dans une chaîne, y compris les fins de ligne, je mettais les chaînes dans une liste.

    Par exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    ch = 'marteau\r\nperceuse\ntournevis\r\nscie'
    print ch
    affiche
    marteau
    perceuse
    tournevis
    scie
    (avec des carrés après marteau et tournevis, en fait)

    Mais
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    ch = 'marteau\r\nperceuse\ntournevis\r\nscie'
    print [ch]
    affiche
    ['marteau\r\nperceuse\ntournevis\r\nscie']






    Ça m’était pratique pour analyser des codes sources de sites.

    Par exemple
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    import urllib
    
    sock = urllib.urlopen('http://www.plantes-carnivores.com/accueil.php')
    fh = sock.read().splitlines(1)
    sock.close()
    
    for i in xrange(402,411):
        print [fh[i]]
    affiche
    ['\treturn ok_return\n']
    ['}\n']
    ['</SCRIPT>\n']
    ['\n']
    ['<style type="text/css">\r\n']
    ['<!--\r\n']
    ['a:link {text-decoration:underline ; color:#0000FF}\r\n']
    ['a:visited {text-decoration:underline ; color:#0000FF}\r\n']
    ['a:hover\t {text-decoration:underline ; color:#FF0000}\r\n']
    On voit que sur ce site, certaines lignes terminent par ’\n’ et d’autres par ’\r\n’, ce qui a son importance quand on analyse un code source avec une regex.




    Maintenant, je fais évidemment
    print repr(ch)
    et
    print repr(fh[i])




    Ce que je veux souligner, c’est que print [ch] affiche la même chose que print [repr(ch)]
    et que c'est la même chose que repr([ch])

    À partir de là, je pense que, de même que print appelle la méthode __str__ des objets de type float, print appelle la méthode __repr__ d’une liste quand on fait print liste.

    Si on fait
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    class A:
        pass
     
    li = [12,'radada',A,100.0/6]
    print 'liste li =',li
    il n’y a pas de problème, ça affiche
    liste li = [12, 'radada', <class __main__.A at 0x010B2150>, 16.666666666666668]

    Mais si on veut grouper dans une même chaîne 'liste li =' et li, on est obligé de remplacer li par repr(li)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    class A:
        pass
     
    li = [12,'radada',A,100.0/6]
    print 'liste li = '+repr(li)
    affiche aussi
    liste li = [12, 'radada', <class __main__.A at 0x010B2150>, 16.666666666666668]





    Les choses se passent donc bien comme si print liste affiche en réalité print repr(liste).
    J’aimerais bien en lire la confirmation formelle.
    En tous cas, il est dès lors compréhensible que
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    b = [100.0/6 , 200.0/6 , 300.0/6]
    c=map(lambda f:round(f,2),b)
    print c
    affiche
    [16.670000000000002, 33.329999999999998, 50.0]
    tandis que si on fait
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    b = [100.0/6 , 200.0/6 , 300.0/6]
    c=map(lambda f:round(f,2),b)
    for el in c:
        print el,
    print
    on obtient
    16.67 33.33 50.0




    La bizarrerie d’affichage que tu as observée, Nico tournai, ne se manifeste que parce que tu fais afficher une liste des valeurs.
    Ce n’est pas la façon la plus fréquente de procéder.
    C’est précisément là que se trouve la raison pour laquelle ça a été de prime abord surprenant, pour moi y compris bien que je connaissais ces histoires de print [ch] et la fonction repr().
    Je crois que c’était utile de bien décrire ça.

  7. #7
    Membre confirmé
    Profil pro
    Inscrit en
    Août 2009
    Messages
    195
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Août 2009
    Messages : 195
    Par défaut
    Merci pour ces précisions sur l'interprétation du print.

    Il ne faut donc toujours pas croire ce qu'on voit, les apparences sont parfois trompeuses...


Discussions similaires

  1. Réponses: 2
    Dernier message: 11/07/2003, 18h24
  2. Problème avec memory mapping
    Par gemai dans le forum C
    Réponses: 13
    Dernier message: 04/07/2003, 09h50
  3. OpenDialog(round 2)
    Par shogoune dans le forum Composants VCL
    Réponses: 4
    Dernier message: 10/06/2003, 14h10
  4. qu'est ce que l'instruction "round"?
    Par isa_21 dans le forum Langage SQL
    Réponses: 2
    Dernier message: 10/03/2003, 10h37
  5. Editeur de MAP en delphi pour jeux directX
    Par PetitScorpion dans le forum DirectX
    Réponses: 5
    Dernier message: 09/07/2002, 18h47

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo