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 :

retirer les nombres entiers d'une liste


Sujet :

Python

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    53
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations forums :
    Inscription : Juin 2008
    Messages : 53
    Par défaut retirer les nombres entiers d'une liste
    Bonjour à tous,

    Contexte :
    Je programme actuellement un script ayant pour but d'identifier des éléments précis dans un fichier CAO de type IGES. Dans ce type de fichier, chaque ligne définit une entité (une ligne, un cercle...) et pour reconnaitre les entités, je dois identifier leurs coordonnées. J'ai donc utilisé readline(), puis strip afin de la transformer en liste (ça marche très bioen jusque là mais après, je bloque).
    Mon problème : dans la liste, il y a des entiers (des caractéristiques des entités qui ne m'intéressent pas - couleur, style...) et les coordonnées X Y Z sous forme de réels (1542.1203, 45544.126, 1.205). Comment puis-je retirer de la liste tous les entiers et ne garder que les réels?

    Exemple :
    liste originale : ['128', '5', '1', '123.6067977', '723.4654977','1', '5', '1', '0', '0', '43.2137977', '3.601277', '223.1067977', '445.12377']
    liste "filtrée" : ['123.6067977', '723.4654977', '43.2137977', '3.601277', '223.1067977', '445.12377']

    J'espère être clair.
    Merci d'avance,

    Fred

  2. #2
    Membre éprouvé
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    76
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Juillet 2008
    Messages : 76
    Par défaut
    Salut !

    Tu peux utiliser la fonction type qui renvoi le type d'un objet. Par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    liste = [128, 5, 1, 123.6067977, 723.4654977, 1, 5, 1, 0, 0, 43.2137977, 3.601277, 223.1067977, 445.12377]
    resultat = []
     
    for n in liste:
            # Si l'élément de la liste est un float, on l'ajoute à la liste résultat
    	if type(n) == type(1.0):
    		resultat.append(n)
     
    print resultat

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    53
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations forums :
    Inscription : Juin 2008
    Messages : 53
    Par défaut
    Merci, ça marche nickel...
    Bonne journée,

    Fred

  4. #4
    Membre averti
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    53
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations forums :
    Inscription : Juin 2008
    Messages : 53
    Par défaut
    En fait, j'ai répondu un peu vite.
    Ça marche bien sur une liste de nombre mais en fait, du fait de l'utilisation de la fonction split, ma liste est une liste de chaine : ['128', '5', '1', '123.6067977', '723.4654977','1', '5', '1', '0', '0', '43.2137977', '3.601277', '223.1067977', '445.12377'] et non [128, 5, 1, 123.6067977, 723.4654977,1,5, 1, 0, 0, 43.2137977,3.601277, 223.1067977, 445.12377].
    Si je transforme les chaines en chiffre, alors je suis obligé de les affecter en int ou float et du coup, la détection du type ne marche plus...
    Je me trompe? Y a t il un moyen de transformer une liste de chaines en liste de nombre sans leur forcer un type?
    Merci d'avance,

    Fred

  5. #5
    Expert confirmé
    Avatar de Guigui_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2002
    Messages
    1 864
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Saône et Loire (Bourgogne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2002
    Messages : 1 864
    Par défaut
    utilise eval
    Sinon, si tes chaînes de caractères sont des flotants, c'est qu'ils contiennent un ".", donc y'a juste à tester l'existence de ce "."

  6. #6
    Membre averti
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    53
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations forums :
    Inscription : Juin 2008
    Messages : 53
    Par défaut
    Guigui,

    Oui, j'y avais pensé mais je trouvai ça un peu lourdeau dans mon script... J'essaie le "eval".
    Merci,

    Fred

  7. #7
    Membre confirmé

    Profil pro
    Inscrit en
    Février 2003
    Messages
    95
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : Etats-Unis

    Informations forums :
    Inscription : Février 2003
    Messages : 95
    Par défaut
    Bonjour,

    Avec une list comprehension et sans eval, c'est pas si lourd :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    lst = ['128', '5', '1', '123.6067977', '723.4654977','1', '5', '1', '0', '0', '43.2137977', '3.601277', '223.1067977', '445.12377']
    print [elem for elem in lst if "." in elem]
    donne bien :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ['123.6067977', '723.4654977', '43.2137977', '3.601277', '223.1067977', '445.12377']
    Cdlt,
    Mathieu

  8. #8
    Membre confirmé
    Avatar de Zorro
    Inscrit en
    Août 2002
    Messages
    137
    Détails du profil
    Informations forums :
    Inscription : Août 2002
    Messages : 137
    Par défaut
    Salut

    Test avec ce code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    >>> L = ['128', '5', '1', '123.6067977', '723.4654977','1', '5', '1', '0', '0', '43.2137977', '3.601277', '223.1067977', '445.12377']
     
    >>> xL = [x for x in L if not isinstance(eval(x), int)]
     
    >>> print xL
     
    ['123.6067977', '723.4654977', '43.2137977', '3.601277', '223.1067977', '445.12377']
    Z

  9. #9
    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
    http://www.biologeek.com/bonnes-prat...stuces-python/

    et descendre avec Ctrl-F à : 'Utilisez in lorsque c'est possible'

    Y a pas à tortiller, 'in' gagne la palme de vitesse à tous les coups:

    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
    from timeit import Timer
    import re
     
    ch = '128 5677 1 123.6067977 723.4654977 1 544 1\n0 0 43.2137977 2.456 3 \n4.678 145.78 3.601277 223.1067977 445.12377'
    lst = ch.split()
    pat = re.compile('\d+\.{1}\d+|\\n')
    def zor(lst):
        return [x for x in lst if not isinstance(eval(x), int)]
    def ey(lst):
        return [ chel for chel in lst if pat.match(chel)]
    def dries(lst):
        return [elem for elem in lst if "." in elem]
     
    iterations = 10000
    tzor = Timer('zor(lst)','from __main__ import zor,lst').timeit(iterations)
    tey = Timer('ey(lst)','from __main__ import ey,lst').timeit(iterations)
    tdries = Timer('dries(lst)','from __main__ import dries,lst').timeit(iterations)
    print '\navec isinstnace-eval\n',zor(lst)
    print tzor,' secondes'
    print '\navec re\n',ey(lst)
    print tey
    print '\navec in\n',dries(lst)
    print tdries,' secondes'
    avec isinstnace-eval
    ['123.6067977', '723.4654977', '43.2137977', '2.456', '4.678', '145.78', '3.601277', '223.1067977', '445.12377']
    16.3025588448 secondes

    avec re
    ['123.6067977', '723.4654977', '43.2137977', '2.456', '4.678', '145.78', '3.601277', '223.1067977', '445.12377']
    1.68407549004

    avec in
    ['123.6067977', '723.4654977', '43.2137977', '2.456', '4.678', '145.78', '3.601277', '223.1067977', '445.12377']
    0.211205614121 secondes

    Je propose une autre solution pour que le résultat conserve l'organisation initiale des données en plusieurs lignes, ce qui peut être utile:
    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
    import re
    from timeit import Timer
     
    ch = '128 5677 1 123.6067977 723.4654977 1 544 1\n0 0 43.2137977 2.456 3 4.678 145.78 3.601277 223.1067977 445.12377'
    lst = ch.split()
    pat = re.compile('\d+\.{1}\d+|\\n')
     
    def ey(lst):
        return [ chel for chel in lst if pat.match(chel) ]
    def ey2(lst): 
        return [ pat.findall(chel) for chel in ch.splitlines() ]
     
    iterations = 10000
    tey = Timer('ey(lst)','from __main__ import ey,lst').timeit(iterations)
    tey2 = Timer('ey2(lst)','from __main__ import ey2,lst').timeit(iterations)
    print ey(lst),'\n',tey,' secondes\n'
    print ey2(lst),'\n',tey2,' secondes'
    ['123.6067977', '723.4654977', '43.2137977', '2.456', '4.678', '145.78', '3.601277', '223.1067977', '445.12377']
    1.77626793349 secondes

    [['123.6067977', '723.4654977'], ['43.2137977', '2.456', '4.678', '145.78', '3.601277', '223.1067977', '445.12377']]
    1.23912983354 secondes
    Bizarrement cette solution (la derniere) est plus rapide que l'autre premiere avec re.

  10. #10
    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 solution mdriesbach amelioree
    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
    from timeit import Timer
    import re
     
    ch = '128 5677 1 123.6067977 723.4654977 1 544 1\n0 0 43.2137977 2.456 3 \n4.678 145.78 3.601277 223.1067977 445.12377'
    lst = ch.split()
    pat = re.compile('\d+\.{1}\d+|\\n')
    def ey(lst):
        return [ chel for chel in lst if pat.match(chel)]
    def ey2(lst): 
        return [ pat.findall(chel) for chel in ch.splitlines() ]
    def dries(lst):
        return [elem for elem in lst if "." in elem ]
    def dries2(lst):
        return [ [el for el in elemen.split() if '.' in el] for elemen in ch.splitlines() ]
     
    iterations = 10000
    tey = Timer('ey(lst)','from __main__ import ey,lst').timeit(iterations)
    tey2 = Timer('ey2(lst)','from __main__ import ey2,lst').timeit(iterations)
    tdries = Timer('dries(lst)','from __main__ import dries,lst').timeit(iterations)
    tdries2 = Timer('dries2(lst)','from __main__ import dries2,lst').timeit(iterations)
     
    print '\navec re\n',ey(lst)
    print tey
    print '\navec in\n',dries(lst)
    print tdries,' secondes'
    print '\n\n\navec re 2\n',ey2(lst)
    print tey2
    print '\navec in 2\n',dries2(lst)
    print tdries2,' secondes'
    avec re
    ['123.6067977', '723.4654977', '43.2137977', '2.456', '4.678', '145.78', '3.601277', '223.1067977', '445.12377']
    2.00179352404

    avec in
    ['123.6067977', '723.4654977', '43.2137977', '2.456', '4.678', '145.78', '3.601277', '223.1067977', '445.12377']
    0.562109988839 secondes



    avec re 2
    [['123.6067977', '723.4654977'], ['43.2137977', '2.456'], ['4.678', '145.78', '3.601277', '223.1067977', '445.12377']]
    1.392408253

    avec in 2
    [['123.6067977', '723.4654977'], ['43.2137977', '2.456'], ['4.678', '145.78', '3.601277', '223.1067977', '445.12377']]
    0.750108742871 secondes
    La solution avec if '.' in reste la plus rapide.

  11. #11
    Membre confirmé
    Avatar de Zorro
    Inscrit en
    Août 2002
    Messages
    137
    Détails du profil
    Informations forums :
    Inscription : Août 2002
    Messages : 137
    Par défaut
    avec isinstnace-eval
    ['123.6067977', '723.4654977', '43.2137977', '2.456', '4.678', '145.78', '3.601277', '223.1067977', '445.12377']
    16.3025588448 secondes

  12. #12
    Membre averti
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    53
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations forums :
    Inscription : Juin 2008
    Messages : 53
    Par défaut
    Merci à tout le monde. Je vais tester tout ça et je vous redis...
    Bonne journée,

    Fred

  13. #13
    Membre averti
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    53
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations forums :
    Inscription : Juin 2008
    Messages : 53
    Par défaut
    Pas encore eu le temps de tout tester mais je vous fais mon retour comme promis.
    J'ai finalement utilisé la fonction 'eval' suivie du test de type. C'est largement assez rapide (peu de listes à traiter et listes courtes) et mon programme devant être débogables par d'autres que moi (qui maitrisent encore moins la prog que moi), je pense que c'est le plus clair et le plus compréhensible.
    Merci pour toutes les réponses,

    Fred

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 2
    Dernier message: 02/11/2008, 20h38
  2. Réponses: 7
    Dernier message: 24/04/2006, 15h48
  3. Réponses: 1
    Dernier message: 24/04/2006, 01h55
  4. recuperer le nombre element d'une liste deroulante
    Par fallered dans le forum Général JavaScript
    Réponses: 3
    Dernier message: 19/10/2005, 14h11
  5. [FLASH MX] Choisir un nombre aléatoire dans une liste
    Par grenatdu55 dans le forum Flash
    Réponses: 4
    Dernier message: 23/04/2005, 21h09

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