Partage
  • Partager sur Facebook
  • Partager sur Twitter

Ecrire du code pythonesque

Sujet résolu
    1 juillet 2013 à 18:14:09

    Bonjour, J'ai écrit trois petite fonctions et je me demandais si il n'y avait pas un moyen plus compressé de les écrire, notamment en utilisant les compréhensions.

    La première fonction construit un dictionnaire inversé : on donne un certains nombres de phrases, et on indique pour chaque mot où il apparaît. Les deux autres fonctions prennent en argument une liste de mots. La deuxième fonction fait une opération logique "ou" sur les phrases où ce mot apparaît et la troisième fonction fait l'opération logique "et".

    Voici donc les codes :

    def makeInverseIndex(strlist):
    
        dico=dict()
        for x,y in enumerate(strlist):
            for z in y.split():
                #print(z)
                if z in dico:
                    dico[z].add(x)
                else:
                    dico[z]={x}
        return dico
    
    def orSearch(inverseIndex, query):
    
        if query==[]:
            set()
        else:
            S=set()
            for x in query:
                S.update(inverseIndex[x])
            return S
    
    
    def andSearch(inverseIndex, query):
    
        if query==[]:
            return set()
        else:
            S=set(inverseIndex[query[0]])
            for x in query[1:]:
                S=S.intersection(inverseIndex[x])
            return S 
    

    Merci d'avance, Bonne journée ;)

    • Partager sur Facebook
    • Partager sur Twitter
    Anonyme
      1 juillet 2013 à 20:50:23

      moyen plus compressé de les écrire

      C'est pas forcément le plus compact qui est le plus lisible... Je te conseille de te renseigner sur le méthode dict.setdefault qui serait utile pour la première fonction.

      Autre chose:

      >>> bool([])
      False
      >>> bool["something"]
      True
      

      Mais, en fait, les tests dans ces fonctions sont inutiles, car le cas particulier qu'ils gèrent (liste vide) peut être géré dans le cas général sans modification: faire un forsur un itérable vide ne pose pas de problème.

      >>> for x in []:

              print("loop")
      >>>
      

      Tu pourrais lire la PEP8 qui donne des conseils pour l'écriture des programmes, elle propose notamment de mettre les noms de variables en minuscules, et de les choisir les plus explicites possible. (je vise les S, x, y, z). Ensuite, je trouve que les opérateurs |= et &= sur les sets sont plus lisibles que set.update et set.intersection. Après tout ça, le code sera bien simplifié, et alors plus facile à exprimer avec des dict/set compréhension, il y a un tuto sur ce site qui explique cela (et les dict, on remplace [] par {key: value ...} et pour les sets par {value ...}). Fais attention à ce que le code reste lisible, et donc de réserver cette syntaxe à des cas simples (une list comprehension de 3 lignes (avec des imbrications, etc., c'est souvent plus dur à comprendre qu'un boucle for équivalente.) :)

      • Partager sur Facebook
      • Partager sur Twitter
        1 juillet 2013 à 21:43:07

        Ok, merci ;)

        Pour le nom des variables, c'est à eu près pareil pour tous les langages, c'est juste que c'est du petit code pour moi, juste facile à écrire. Pour le reste, j'y avais pensé sans en être sur.

        Je bloque cependant à la transformation en "set compréhension", je me prend une erreur du type :

        "unhashable type: set"

        avec le code suivant :

        def orSearch(inverseIndex, query):
        
        return {inverseIndex[x] for x in query}
        
        </pre>

        Je vois d'où elle sort, mais je ne sais pas comment régler ce problème, je dois faire référence au set en construction, mais ce n'est pas possible en python.

        • Partager sur Facebook
        • Partager sur Twitter
        Anonyme
          1 juillet 2013 à 22:10:55

          il faut en plus itérer sur inverseIndex[x]:

          {y for x in query for y in inverseIndex[x]}
          
          • Partager sur Facebook
          • Partager sur Twitter
            1 juillet 2013 à 22:59:45

            J'ai trouvé juste après avoir posté, je pensais juste qu'il y avait plus simple !

            Merci ;) !

            • Partager sur Facebook
            • Partager sur Twitter
            Anonyme
              2 juillet 2013 à 8:09:56

              ou bien alors

              import functools
              reduce(set.union, (inverseIndex[x] for x in query), set())
              

              mais c'est moins lisible

              • Partager sur Facebook
              • Partager sur Twitter

              Ecrire du code pythonesque

              × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
              × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
              • Editeur
              • Markdown