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 :

Comprehension list avec break ?


Sujet :

Python

  1. #1
    Nouveau membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2016
    Messages
    26
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Pologne

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2016
    Messages : 26
    Points : 28
    Points
    28
    Par défaut Comprehension list avec break ?
    Bonjour,

    Avez-vous une idee pour optimiser le code suivant ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    result = []
    for r in self.reports:
                for k in kwargs:
                    if r[k] != kwargs[k]: break
                else: result.append(r)
    J'ai essaye de faire:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    result = [ r[k] if r[k] == kwargs[k] else break for r in self.reports for k in kwargs ]
    mais malheureusement le "break" ne passe pas dans une comprehension list.

    Une idee quelqu'un ?

    Merci d'avance

  2. #2
    Membre confirmé

    Homme Profil pro
    Bidouilleur
    Inscrit en
    Avril 2016
    Messages
    721
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Bidouilleur

    Informations forums :
    Inscription : Avril 2016
    Messages : 721
    Points : 503
    Points
    503
    Billets dans le blog
    1
    Par défaut
    Salut.

    L'optimisation d'un code n'a strictement aucune relation avec le nombre de lignes de code.

    Ce que tu souhaites faire est justement la réduction du nombres de lignes, alors mieux vaut un code un peu plus long et compréhensible ou un code plus court et imbitable que tu auras peine toi-même à analyser lorsque tu reviendras plus tard dessus ?
    Le temps ronge l'amour comme l'acide.

  3. #3
    Expert éminent
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    3 823
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 823
    Points : 7 119
    Points
    7 119
    Par défaut
    On peut optimiser, mais pour cela il faut exprimer le problème, au moins savoir ce que vous souhaitez faire exactement et honnêtement je pense que votre optimisation n'est pas lié à un break mais plutôt à la conception pour résoudre le problème.

    Comme le dit bistouille, si une optimisation n'est qu'une optimisation sur le nombre de lignes et qu'elle nuit à la lisibilité du code, alors n'optimisez pas!
    Allez voir le zen de python, et vous verrez cette ligne

    Readability counts.
    Celui qui trouve sans chercher est celui qui a longtemps cherché sans trouver.(Bachelard)
    La connaissance s'acquiert par l'expérience, tout le reste n'est que de l'information.(Einstein)

  4. #4
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 283
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 283
    Points : 36 770
    Points
    36 770
    Par défaut
    Salut,

    Maintenant qu'on vous a bien expliqué que "break" dans une compréhension list n'allait probablement pas aller plus vite. Pour ceux que çà intéresse, on peut utiliser la forme d'iter avec sentinelle:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    >>> s = iter('aaaexxx')
    >>> [ x for x in iter(lambda: next(s), 'e') ]
    ['a', 'a', 'a']
    >>>
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  5. #5
    Nouveau membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2016
    Messages
    26
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Pologne

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2016
    Messages : 26
    Points : 28
    Points
    28
    Par défaut
    Hmm, quant a l'optimisation et le nombre de lignes de code, dans ce cas precis je ne suis pas d'accord.
    Une comprehension list permettrait de supprimer le 'append' qui en Python est tres couteux car il:

    - recopie en entier la liste a agrandir
    - ajoute plus d'elements qu'il n'en faut, c'est-a-dire prevoit de l'espace pour de futurs elements.

    Par ailleurs, il me semble avoir remarque qu'en regle generale les comprehension lists sont neanmoins plus rapides....

  6. #6
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 283
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 283
    Points : 36 770
    Points
    36 770
    Par défaut
    Citation Envoyé par JacekB Voir le message
    Hmm, quant a l'optimisation et le nombre de lignes de code, dans ce cas precis je ne suis pas d'accord.
    Une comprehension list permettrait de supprimer le 'append' qui en Python est tres couteux car il:

    - recopie en entier la liste a agrandir
    - ajoute plus d'elements qu'il n'en faut, c'est-a-dire prevoit de l'espace pour de futurs elements.

    Par ailleurs, il me semble avoir remarque qu'en regle generale les comprehension lists sont neanmoins plus rapides....
    Le soucis n'est pas dans compréhension list ou pas: juste par le manque d'informations sur le problème à résoudre (aller plus vite est un peu short)... qui pourrait être traité plus efficacement avec d'autres algos ou l'usage d'une bibliothèque externe.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  7. #7
    Expert éminent
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    3 823
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 823
    Points : 7 119
    Points
    7 119
    Par défaut
    Autre possibilité moins belle que celle de wiztricks

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    import itertools
     
    res = itertools.takewhile(lambda x: x != 'e', list('aaaexxx'))
    print(list(res))
    EDIT: Je trouve quand même que pour ce genre d'exercice rien de tel que d'utiliser en plusieurs ligne le générateur équivalent à takewhile mais sans itertools

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    def get_x_gen2(my_list, stop):
        for x in my_list:
            if x == stop: break
            yield x
    Celui qui trouve sans chercher est celui qui a longtemps cherché sans trouver.(Bachelard)
    La connaissance s'acquiert par l'expérience, tout le reste n'est que de l'information.(Einstein)

  8. #8
    Expert éminent
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    3 823
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 823
    Points : 7 119
    Points
    7 119
    Par défaut
    Citation Envoyé par JacekB Voir le message
    Une comprehension list permettrait de supprimer le 'append' qui en Python est tres couteux
    à ce point là ? Avez-vous profilé votre code ?

    Avez-vous testé le gain entre append et une comprehension list sur quelques millions d'itérations ?
    Ce qui en pratique, qui puis est ne semble pas être le cas, je veux dire que vous n'avez pas quelques millions d'itérations à faire, je me trompe ?

    recopie en entier la liste a agrandir
    Ah! et cela, vous êtes sûr que la comprehension list ne le fait pas ?

    ajoute plus d'elements qu'il n'en faut, c'est-a-dire prevoit de l'espace pour de futurs elements.
    Vous parlez d'allocations mémoire, mais vous pensez ne pas avoir suffisamment de RAM pour faire le travail ?
    Celui qui trouve sans chercher est celui qui a longtemps cherché sans trouver.(Bachelard)
    La connaissance s'acquiert par l'expérience, tout le reste n'est que de l'information.(Einstein)

  9. #9
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 689
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 689
    Points : 30 983
    Points
    30 983
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par JacekB Voir le message
    Bonjour,

    Avez-vous une idee pour optimiser le code suivant ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    result = []
    for r in self.reports:
                for k in kwargs:
                    if r[k] != kwargs[k]: break
                else: result.append(r)
    Bonjour

    Déjà supprimer ce "else" inutile...
    Sinon je n'arrive pas trop à me représenter ce que signifie "k". Parce que tantôt il est utilisé comme indice de boucle, tantôt il est utilisé comme élément d'itération de kwargs.
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  10. #10
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 283
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 283
    Points : 36 770
    Points
    36 770
    Par défaut
    Citation Envoyé par Sve@r Voir le message
    Déjà supprimer ce "else" inutile...
    Comment çà inutile?
    Peut être que vous ne connaissez pas encore la construction for...else...

    Sinon je n'arrive pas trop à me représenter ce que représente "k". Parce que tantôt il est utilisé comme indice de boucle, tantôt il est utilisé comme élément d'itération.
    Ce sont les différentes clés du dictionnaire kwargs.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  11. #11
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 689
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 689
    Points : 30 983
    Points
    30 983
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par wiztricks Voir le message
    Comment çà inutile?
    Peut être que vous ne connaissez pas encore la construction for...else...
    Euh non, j'ai pensé que c'était le "else" du "if" mal indenté... Ok un truc à aller apprendre avant de revenir

    Citation Envoyé par wiztricks Voir le message
    Ce sont les différentes clés du dictionnaire kwargs.
    Vu. Comme j'ai l'habitude d'utiliser explicitement les méthodes "keys()" ou "viewkeys()", j'avais oublié qu'on obtenait le même résultat en itérant directement le dico.

    edit: ok j'ai appris le" for... else" et j'ai adoré car il m'arrive souvent de chercher si un truc se trouve dans une liste mais de faire un traitement s'il ne s'y trouve pas =>auparavant je passais par un flag mais là, ça va me simplifier pas mal de choses

    Et je comprends maintenant mieux l'algo. Donc d'après ce que j'ai compris, il me semble que "reports" contient une liste de dicos, et que l'algo stocke dans result chaque dico de "reports" ayant au-moins toutes les clefs et valeurs de kwargs.
    Partant de là, et si on fait abstraction de considérations de "plus lisible/moins lisible, plus rapide/moins rapide" ; c'est à dire qu'on se concentre juste sur la demande initiale à savoir convertir cet algo en liste par intention ; est-ce que ceci result=[r for r in self.reports if all(r[k] == kwargs[k] for k in kwargs)] ne conviendrait pas ???
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  12. #12
    Nouveau membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2016
    Messages
    26
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Pologne

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2016
    Messages : 26
    Points : 28
    Points
    28
    Par défaut
    Citation Envoyé par fred1599 Voir le message
    à ce point là ? Avez-vous profilé votre code ?

    Avez-vous testé le gain entre append et une comprehension list sur quelques millions d'itérations ?
    Ce qui en pratique, qui puis est ne semble pas être le cas, je veux dire que vous n'avez pas quelques millions d'itérations à faire, je me trompe ?



    Ah! et cela, vous êtes sûr que la comprehension list ne le fait pas ?



    Vous parlez d'allocations mémoire, mais vous pensez ne pas avoir suffisamment de RAM pour faire le travail ?
    Oui, j'ai fait des comparaisons, les comprehension list sont nettement plus rapides que des append, vous trouverez de nombreuses publications sur ce sujet.
    Par exemple: https://wiki.python.org/moin/PythonS...erformanceTips
    a la rubrique "loops": List comprehensions were added to Python in version 2.0 as well. They provide a syntactically more compact and more efficient way of writing the above for loop


    Concernant le nombre d'iterations a faire, se ne sont pas quelques millions, mais quelques dizaines de millions.

    Quant a l'allocation memoire, encore une fois, les append sont a eviter autant que faire se peu....

  13. #13
    Nouveau membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2016
    Messages
    26
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Pologne

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2016
    Messages : 26
    Points : 28
    Points
    28
    Par défaut
    Citation Envoyé par fred1599 Voir le message
    Ah! et cela, vous êtes sûr que la comprehension list ne le fait pas ?
    Bien sur que non, une comprehension list ne peut pas recopier les elements de la premiere liste, vu qu'elle n'agrandi pas une liste preexistante....
    Regardez le code source de Python.....

  14. #14
    Expert éminent
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    3 823
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 823
    Points : 7 119
    Points
    7 119
    Par défaut
    Sur l'itération pure vous allez gagné 50% ce qui représente sur une dizaine de millions d'itération environ 8/10 de seconde, elle ne se voit donc pas, c'est ce qui se passe dans l'itération qui est à optimiser.

    Bien sur que non, une comprehension list ne peut pas recopier les elements de la premiere liste, vu qu'elle n'agrandi pas une liste preexistante.... Regardez le code source de Python.....
    Pour agrandir une liste, on utilise l'opérateur + ou la méthode extend. Je ne vois pas où vous voulez en venir.

    La possibilité de travailler avec les listes restent limitée, et en règle générale on se tourne vers des modules comme numpy, pandas, ...

    Si vous voulez plus de performance, vous pouvez voir du côté de PyPy ou d'un interfaçage C/C++/Fortran... ou carrément changer de langage.

    wiztricks a déjà exprimé le fait qu'il faudra plus d'informations concernant votre problème, mais sans réponse à l'heure actuelle.
    Celui qui trouve sans chercher est celui qui a longtemps cherché sans trouver.(Bachelard)
    La connaissance s'acquiert par l'expérience, tout le reste n'est que de l'information.(Einstein)

Discussions similaires

  1. [Struts] Tester la taille d'une List avec un Tag Logic
    Par yolepro dans le forum Struts 1
    Réponses: 5
    Dernier message: 24/08/2007, 10h28
  2. Créer une liste avec taille inconnue
    Par C_C dans le forum Prolog
    Réponses: 3
    Dernier message: 19/11/2005, 12h46
  3. Zone de liste avec 2 couleurs differentes
    Par uloaccess dans le forum Access
    Réponses: 2
    Dernier message: 02/11/2005, 17h10
  4. Liste avec ascenceur
    Par Guitch dans le forum Balisage (X)HTML et validation W3C
    Réponses: 7
    Dernier message: 20/10/2004, 15h32
  5. [MFC] creer une liste avec des check????
    Par ginounet dans le forum MFC
    Réponses: 4
    Dernier message: 16/06/2004, 11h47

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