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 :

Ou ranger les objets dans Python ?


Sujet :

Python

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Février 2006
    Messages
    34
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 34
    Points : 24
    Points
    24
    Par défaut Ou ranger les objets dans Python ?
    Bonjour à tous,

    juste une petite question...
    Ou ranger les objets dans Python ?
    aujourd'hui, après avoir crée un objet, je le range dans un dictionnaire
    exemple :
    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
     
    class Point():
        """ Definition d'un objet Point"""
        def __init__(self,Id):
            self.Id=Id
            self.X=0
            self.Y=0
            self.Z=0
    if __name__ == '__main__':
     
      Dico={} # Création d'un dictionnaire
     
      Dico[1234]=Point(1234) # Juste après la création, je range l'objet dans un                Dictionnaire
     
      extraction_valeur=Dico[1234].X    # pour retrouver l'objetpar son Id, j'utilise les cles du dictionnaire
      print(extraction_valeur)
    Cette solution marche, mais est ce la plus pertinente, en effet, je doit aujourd'hui utiliser un dictionnaire avec 124000 Points, et ça rame ... beaucoup, lorsque je vérifie la presence d'un point dans le dictionnaire,
    Donc y a t-il une méthode plus performante, et si oui, laquelle ?

    Par avance merci,
    Loic

  2. #2
    Membre éclairé
    Homme Profil pro
    heu...
    Inscrit en
    Octobre 2007
    Messages
    648
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : heu...

    Informations forums :
    Inscription : Octobre 2007
    Messages : 648
    Points : 773
    Points
    773
    Par défaut
    avec 124000 Points, et ça rame ... beaucoup, lorsque je vérifie la présence d'un point dans le dictionnaire,
    C'est normal, plus un dictionnaire est grand, et plus il sera long pour l'ordi de trouver la bonne clé, peut-être devrais-tu stocker tes objets dans une liste, je pense (sans certitude) que ces dernières sont un peu plus rapide, dans le sens où si tu connais l'index, la liste ayant un classement, y'a plus véritablement d'étape de recherche comme pour un dico (qui lui n'a pas de classement), où tout du moins elle n'est pas aussi longue.

    Sinon, si tu sais dériver une class, tu pourrait faire dériver la classe de tes objets d'une liste, ça pourrait de la sorte coller parfaitement à tes besoins, par contre ça n'irait pas pour autant plus vite

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Février 2006
    Messages
    34
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 34
    Points : 24
    Points
    24
    Par défaut
    Dans le sens où si tu connais l'index, ...
    Merci pour la réponse, mais
    Mon problème est d'associer l'index à l'identifiant de mon objet (qui me sert aujourd'hui pour retrouver/utiliser mon objet)
    la liste me renvois juste la référence de cette instance (voir ci dessous) ou alors j'ai pas tout compris

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
     Liste=[] # Création d'une liste  
      Liste.append(Point(1234)) # Juste après la création, je range l'objet dans un liste
      print Liste[0]
     
      ##
      ##  >>> 
      ##  <__main__.Point instance at 0x01219328> La reponse de python
    Une solution serait :
    1- de dériver la class Int,
    2- de ranger ces instances dans la liste
    Ce qui me permettra (peut être) de retrouver mon identifiant ...

    je voudrais savoir avant de me lancer dans une telle aventure, si cette méthode est susceptible de répondre à mon problème, ne vais-je pas réinventer la class dictionnaire en moins bien ???

    Mais comment y font les vrais programmeur ???

  4. #4
    Membre éclairé
    Homme Profil pro
    heu...
    Inscrit en
    Octobre 2007
    Messages
    648
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : heu...

    Informations forums :
    Inscription : Octobre 2007
    Messages : 648
    Points : 773
    Points
    773
    Par défaut
    En fait, j'me suis dit qu'une classe Container dérivée d'un dico pourrait fonctionner... le principe de cette classe étant.... voyons un exemple, ce sera plus explicite
    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
    >>> a=Container()
    >>> a[1258]=1258
    >>> a[1258]
    1258
     
    #bon à première vue, rien de neuf, mais regardons un attribut de cette classe:
    >>> a.dict
    {1200:{1258:1258}}
     
    #continuons de rentré des valeurs
    >>> a[1289]=1289
    >>> a[518]=518
    >>> a.dict
    {500:{518:518}
    1200:{1289:1289, 1258:1258}
    En fait, le but de cette classe est de classer les clé dans des "tranches", ce qui veut dire que toutes les clés >=1200 <1300 seront stockées dans un dictionnaire dont la clé est 1200...
    J'ai du mal à m'expliquer mais j'éspère que t'as piger le principe, en théorie quand on appellera une valeur (ex:986), plutôt que de chercher parmi 1700 clés (en admettant qu'il n'y en ai pas plus), l'ordi cherchera dans un premier temps la clé 900 parmi les 17 disponibles, puis il cherchera enfin 986 parmi l'eventuelle centaine de clé présente, cela devrait -en théorie donc- mettre moins de temps que de chercher parmis 1700 clés désordonnées...
    Voici le code de cette classe :
    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
    class Container(dict):
        def __init__(self):
            self.dict={}
        def __setitem__(self,key,value):
            #admettons 134
            if type(key)!=int: raise ContainerIntError
            key_range=key/100*100
            if self.dict.has_key(key_range):
                self.dict[key_range][key]=value
            else:
                self.dict[key_range]={key:value}
        def __getitem__(self,key):
            key_range=key/100*100
            return self.dict[key_range][key]
     
    class ContainerIntError(Exception):
        def __str__(self): return 'Key must be integer !'
    Evidemment on pourrait pousser la classification plus loin encore, mais je me dis qu'encore plus de classification, encore plus de mémoire prise... à toi de voir...

  5. #5
    Membre éclairé
    Homme Profil pro
    Inscrit en
    Janvier 2006
    Messages
    476
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Corse (Corse)

    Informations forums :
    Inscription : Janvier 2006
    Messages : 476
    Points : 831
    Points
    831
    Par défaut
    bonjour et en utilisant tout simplement un sgbd c'est performant et c'est fait pout ça

  6. #6
    Membre éclairé
    Homme Profil pro
    heu...
    Inscrit en
    Octobre 2007
    Messages
    648
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : heu...

    Informations forums :
    Inscription : Octobre 2007
    Messages : 648
    Points : 773
    Points
    773
    Par défaut
    C'est quoi sbdg ?

    Sinon, je viens de passer ma classe à un timeit et je l'ai comparée avec un dictionnaire équivalent et autat de clés (1600), et ma classe n'est plus rapide qu'en théorie...
    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
    a=Container()
    >>> for x in range(1600):
    	a[x]=x
     
    >>> b={}
    >>> for x in range(1600):
    	b[x]=x
     
    >>> import timeit
    >>> timeit.Timer('''a[1592]
    a[1000]
    a[596]''','from __main__ import a,b').timeit()
    2.2382217065716694
    >>> timeit.Timer('''b[1592]
    b[1000]
    b[596]''','from __main__ import a,b').timeit()
    0.23214176056998426

  7. #7
    Membre à l'essai
    Profil pro
    Inscrit en
    Février 2006
    Messages
    34
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 34
    Points : 24
    Points
    24
    Par défaut
    Sauf erreur de ma part, un SGBD, est un Système de Gestion de Base de données ....
    Mais je ne les connais pas suffisamment pour les utiliser,

    je me pose toujours la question de savoir si je doit après chaque extraction d'un point (pour son éventuel modification), je doit le ranger tout de suite ou le laisser dans le curseur de la SGBD ....

  8. #8
    Membre à l'essai
    Profil pro
    Inscrit en
    Février 2006
    Messages
    34
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 34
    Points : 24
    Points
    24
    Par défaut
    ma classe n'est plus rapide qu'en théorie...

    2.238 second vs 0.232 secondes
    Bel efforts !!! lol dis moi, dans ta boite tu bosse pour la concurence
    merci quand même ....

  9. #9
    Membre chevronné
    Avatar de kedare
    Homme Profil pro
    Network Automation Engineer
    Inscrit en
    Juillet 2005
    Messages
    1 548
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Network Automation Engineer

    Informations forums :
    Inscription : Juillet 2005
    Messages : 1 548
    Points : 1 861
    Points
    1 861
    Par défaut
    si non tu peut essayer sqlite en :memory:

  10. #10
    Membre expérimenté
    Homme Profil pro
    Inscrit en
    Mars 2007
    Messages
    941
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2007
    Messages : 941
    Points : 1 384
    Points
    1 384
    Par défaut
    A quoi te sert réellement l'attribut 'Id', hormis retrouver les objets dans un dictionnaire ? Les objets possèdent déjà naturellement un identifiant unique, qui est leur adresse en mémoire. Tu pourrais donc simplement remplacer les utilisations de l'Id par une référence à l'objet en mémoire. Le seul intérêt que je vois d'avoir cet ID, c'est pour la persistance des données. Mais dans ce cas, lors du chargement des données en mémoire, il suffirait de remplacer les Id par des références aux objets. Cela impose seulement de faire attention aux dépendances dans les données (càd à l'ordre de création des objets en mémoire). En fait, si tu n'as pas de contrainte sur le format d'enregistrement des données, cPickle suffirait peut-être.

  11. #11
    Membre à l'essai
    Profil pro
    Inscrit en
    Février 2006
    Messages
    34
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 34
    Points : 24
    Points
    24
    Par défaut
    pleins de chose intéressantes dans ce texte (meme si je ne comprends pas tout ),
    j'utilise en effet l'attribut 'Id' pour retrouver mes objets dans un dictionnaire, c'est la seule solution que je connais pour les retrouver par leur petit nom

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Tu pourrais donc simplement remplacer les utilisations de l'Id par une référence à l'objet en mémoire.
    ça je sais pas faire .... , tu as un petit exemple peut être ...

    pour cPickle je vais voir ce que cela peux m'apporter....

    Autrement pour vous donner plus d'infos sur mon projet, je dois exploiter des données issus de fichiers de température en mode texte (~20 fichiers de 500 Mo à 1Go), ces fichiers représentent par exemple la température à un instant t et à une position défini, mon objectif est de fournir les maximums pour chaque points, voila, voila, vous savez tout.....

    Mon algorithme est donc le suivant :
    1- je reduit mon étude à 124000 Points ce qui represente plus que 10 % des données. Pour chaqun de ces points je cree un objet pour stocker ses informations (4 ou 5 pas plus), cet objet je le range dans un dictinnaire

    2- puis j'ouvre, un-part-un les 20 fichiers de 500Mo (ou plus) pour en extraire les températures, et quand on trouve une valeur qui est dans le dictionnaire, je compare à sa valeur maximal, et je la remet à jour s besoins, ...
    voila, voila, c'est tout bête

  12. #12
    Membre éclairé
    Homme Profil pro
    Inscrit en
    Janvier 2006
    Messages
    476
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Corse (Corse)

    Informations forums :
    Inscription : Janvier 2006
    Messages : 476
    Points : 831
    Points
    831
    Par défaut
    bonjour,
    je me repete mais le mieux est d'utiliser une base de données,
    de plus au cas où tu voudrais faire des requetes spatiales entre différents points je te conseille d'utiliser postgresql avec sa cartouche geographique postgis

  13. #13
    Membre expérimenté
    Homme Profil pro
    Inscrit en
    Mars 2007
    Messages
    941
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2007
    Messages : 941
    Points : 1 384
    Points
    1 384
    Par défaut
    Vu ce complément d'information, je rejoins xavier-Pierre; un SGBD serait bien plus adapté...

  14. #14
    Membre averti Avatar de alexdevl
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    265
    Détails du profil
    Informations personnelles :
    Âge : 54
    Localisation : France, Loire (Rhône Alpes)

    Informations forums :
    Inscription : Avril 2007
    Messages : 265
    Points : 344
    Points
    344
    Par défaut test sgbd
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    "un SGBD serait bien plus adapté..."
    Mon avis :

    a)Peux t on dire que la rapidité est proportionnelle à la simplicité du type de variable pour des petites bases.
    b) Mais tend vers une constante pour des données structurées ?

    Je m'explique :

    a) Avec une liste (avec l'index en n° de point) le temps est de 0.27

    b) Par curiosité J'ai paramétré une bd sqlite en mémoire.
    C'est pas vraiment plus rapide...mais plutôt beaucoup plus long.
    Ceci qui me semble normal puisque c'est un modèle structuré.
    (D'ailleurs le temps semble constant suivant la taille de la base)

    Le dico entre les deux est à 0.34

    Bref..

    Dico 0.34049690673
    Liste 0.272945863231
    BDD en mémoire 13.0855527728

    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
    42
    43
    44
    45
     
    #!/usr/bin/env python
    # -*- coding: iso-8859-1 -*-
    import timeit
    import sqlite3
     
    class Point():
        """ Definition d'un objet Point"""
        def __init__(self,Id):
            self.Id=Id
            self.X=0
            self.Y=0
            self.Z=0
    if __name__ == '__main__':
     
        #----------Avec un Dico
        Dico={} # Création d'un dictionnaire
        for i in range(124000):
            Dico[i]=Point(i) # Juste après la création, je range l'objet dans un                Dictionnaire
     
        # pour retrouver l'objetpar son Id, j'utilise les cles du dictionnaire
        t=timeit.Timer('''extraction_valeur=Dico[1234].X ''','''from __main__ import Dico''').timeit()
        print "Dico",t
     
        #----------Avec une liste
        lst=[] # Création d'une liste
        for i in range(124000):
            lst.append(Point(i)) # Juste après la création, je range l'objet dans une liste
     
           # pour retrouver l'objetpar son Id, j'utilise les cles du dictionnaire
        t=timeit.Timer('''extraction_valeur=lst[1234].X ''','''from __main__ import lst''').timeit()
        print "Liste",t
     
     
        #----------Avec une base SQLITE
        connection = sqlite3.connect(':memory:') #Création d'un objet connection à la BDD, connection ou création si pas d'existence
        cursor = connection.cursor() #Création de l'objet curseur
        #  Création de la table
        cursor.execute("CREATE TABLE Points (id INTEGER PRIMARY KEY,X INTEGER,Y INTEGER,Z INTEGER)")
        for i in range(124000):
     
            cursor.execute("insert into Points (id,X,Y,Z) values (?, ?,?,?)", (i,0,0,0))  
     
        t=timeit.Timer('''cursor.execute('SELECT * FROM Points where ID=5') ''','''from __main__ import cursor''').timeit()
        print "BDD en mémoire",t

  15. #15
    Membre expérimenté
    Homme Profil pro
    Inscrit en
    Mars 2007
    Messages
    941
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2007
    Messages : 941
    Points : 1 384
    Points
    1 384
    Par défaut
    Le gain n'est pas à ce niveau-là; l'idée est de mettre toutes les données dans une DB, de définir des index où il faut, et de faire des requêtes plus complexes (avec jointures, groupements, etc.) pour récupérer directement l'info qui t'intéresse. Un SGDB relationnel, c'est pas juste des fichiers plats avec une indexation de la clé primaire... Faire travailler le SGBD, avec ses algorithmes avancés et son code optimisé, pas Python. Et vu la quantité de donnée, sqlite sera un peu dépassé je pense (+1 pour postgres).
    Je n'ai jamais utilisé de modules gérant les "requêtes spatiales", mais effectivement, si elles sont nécessaires, c'est sûrement un must.

  16. #16
    Membre habitué
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    119
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 119
    Points : 139
    Points
    139
    Par défaut
    Pour moi, le problème vient plutot de ce que tu veux faire avec ces points. Pour l'instant, tu dis que tu veux "verifier la présence d'un point" et "calculer le max de temperature d'un point". Si verifier la presence d'un point, c'est regarder qu'il y a un point avec les memes x et y et que c'est la seule opération que tu veux faire, je suggère de faire un dictionnaire indexé sur (x,y). Du coup, retrouver un point qui correspond à des coordonnées est très rapide.

    Bien sur, la sgbd permettra de faire des requetes plus variées par la suite ou meme de tout charger d'un coup et de faire une requete d'un coup pour trouver le max. Mais la premiere solution devrait suffire.

Discussions similaires

  1. Lire un fichier binaire et ranger les données dans un tableau
    Par Flaherty Mc Coillean dans le forum Débuter
    Réponses: 1
    Dernier message: 31/05/2009, 17h45
  2. Réponses: 2
    Dernier message: 09/12/2008, 09h57
  3. Centrer verticalement les objet dans un flow layout ?
    Par Djobird dans le forum Agents de placement/Fenêtres
    Réponses: 1
    Dernier message: 05/09/2008, 09h08
  4. Ranger les .dll dans le .exe
    Par imados dans le forum VB.NET
    Réponses: 19
    Dernier message: 16/09/2007, 16h57
  5. Ranger ses objets dans LDAP avec les OU (OrganizationalUnit)
    Par Fuego dans le forum Windows Forms
    Réponses: 1
    Dernier message: 20/02/2007, 15h04

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