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

Calcul scientifique Python Discussion :

Pouvoir utiliser une fonction à 2 arguments pour trier une liste avec "sort" [Python 3.X]


Sujet :

Calcul scientifique Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2019
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2019
    Messages : 6
    Points : 6
    Points
    6
    Par défaut Pouvoir utiliser une fonction à 2 arguments pour trier une liste avec "sort"
    Bonjour !

    Je suis actuellement sur un projet pour mes études d'informatique. Le projet consiste de trier une liste de points (x, y) (avec les x et y positif et entier) et de les comparer pour garder un maximum de points qui possèdent une distance supérieur à un diamètre donné ("r").
    J'ai donc trié la liste avec les x croissant puis en renversant une copie de la liste initial

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    l1.sort( key = operator.itemgetter(0) )
    l2 = list(l1)
    l1 = traitementPoints(l1, r)
     
    l2.reverse()
    l2 = traitementPoints(l2, r)
    Puis j'ai fais la même chose mais cette fois pour les y en remplacant "operator.itemgetter(0)" par "operator.itemgetter(1)"
    Jusque là tout va bien ^^

    A présent je voulais trier la liste grâce au produit scalaire, j'ai créé cette fonction :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    def produitScalaire(u, v):
    	return u[0]*v[0] + u[1]*v[1]
    Mais là où je n'arrive pas à trouver de réponse sur internet c'est pour le passage de la fonction sur la fonction "sort()"

    J'ai donc essayer d'écrire (avec (3,2) un vecteur de référence) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    l.sort( key = lambda x: produitScalaire( (3, 2), x ) )
    print(l)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    l.sort( key = produitScalaire( (3, 2) ) )
    print(l)
    Mais j'ai toujours cette erreur :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    "print(l)
            ^
    SyntaxError: invalid syntax"
    Je vous remercie d'avance pour votre aide !
    Je suis nouveau sur ce forum (qui est mon premier forum ^^), j'espère ne pas avoir fais de faux pas sur la création du sujet ou autre , sinon j'essayerai de les corriger ^^

  2. #2
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 355
    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 355
    Points : 36 883
    Points
    36 883
    Par défaut
    Salut,

    En général, lorsqu'un SyntaxError arrive de nulle part, il faut s'assurer que l'instruction précédente se termine bien (en général on a oublié de compter le nombre de parenthèses ouvrantes/fermantes).

    - W

  3. #3
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2019
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2019
    Messages : 6
    Points : 6
    Points
    6
    Par défaut
    Merci pour ta réponse ^^

    Je dois admettre que je suis assez confus et désolé... Car effectivement je n'ai pas fais assez attention à une parenthèse oubliée

    J'aurai juste une dernière question
    Est-ce possible d'effectuer le calcul ci-dessous plus rapidement ? Car j'ai su hier qu'il fallait mieux utiliser "operator.itemgetter" que "lambda"

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    u = (3, 2)
    l.sort( key = lambda x: produitScalaire( u, x ) )
    En m'excusant encore pour l'erreur que j'ai faite et pour l'embêtement occasionné...

    Edit :

    Car lorsque j'essaye comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    l.sort( key = produitScalaire( u, ( operator.itemgetter(0), operator.itemgetter(1) ) ) )
    J'ai cette erreur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    return u[0]*v[0] + u[1]*v[1]
    TypeError: unsupported operand type(s) for *: 'int' and 'operator.itemgetter'

  4. #4
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 355
    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 355
    Points : 36 883
    Points
    36 883
    Par défaut
    Citation Envoyé par RiivaG Voir le message
    Est-ce possible d'effectuer le calcul ci-dessous plus rapidement ? Car j'ai su hier qu'il fallait mieux utiliser "operator.itemgetter" que "lambda"
    Il faut utiliser operator.itemgetter lorsque çà fait du sens... et c'est à voir au cas par cas.
    D'abord, il faut comprendre qu'operator.itemgetter(n) retourne une fonction qui prendra une séquence en argument pour en retourner le n-ième élément:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    >>> f = operator.itemgetter(3)
    >>> f('012345')
    '3'
    >>>
    Ensuite, dans list.sort(key=...), l'argument passé à key sera une fonction qui recevra chaque élément de la liste pour retourner ce qui permettra de comparer.
    Donc avec key = produitScalaire( u, ( operator.itemgetter(0), operator.itemgetter(1) ) ), on assigne à key le retour de la fonction produitScalaire. Et pour çà elle est appelée avant même de commencer à trier avec ( c(0), operator.itemgetter(1) ) en 2nd argument.

    Et comme çà ne sait pas multiplier un entier par une fonction, çà plante.
    => pour appliquer la fonction produit_Scalaire aux différents éléments de la liste, il faudra toujours fabriquer une autre fonction appelée "fermeture" (avec ou sans lambda) qui dira comment appeler la fonction avec chaque élément.

    Et si vous voulez ajouter des operator.itemgetter la dedans, çà devrait pouvoir s'écrire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    l.sort( key = lambda x: produitScalaire( u, (  operator.itemgetter(0)(x),  operator.itemgetter(1)(x) ) ))
    Et comparé à:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    l.sort( key = lambda x: produitScalaire( u, x))
    passer directement le "x" plutôt que d'en créer un autre avec deux appels de fonctions sera moins performant et inutile.

    Quoique vous lisiez dans les forums, vous devez d'abord comprendre pour savoir si ce qu'on vous raconte s'applique ou pas à votre cas.

    - W

  5. #5
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2019
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2019
    Messages : 6
    Points : 6
    Points
    6
    Par défaut
    Je vous remercie encore une fois pour votre réponse ! ^^

    Je comprends beaucoup mieux l'utilisation de "operator.itemgetter()".

    Donc si j'ai bien compris, dans le cas présent le mieux reste d'utiliser ce code ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    l.sort( key = lambda x: produitScalaire( u, x))
    Il n'y a pas de moyen d'optimiser un peu plus le temps de traitement ?

    (Je demande ça car j'ai une liste de 10 000 points à traiter, et je travaille dessus actuellement, ça peut prendre pas mal de temps Du coup je cherche à optimiser le plus de temps possible ^^)

  6. #6
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 355
    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 355
    Points : 36 883
    Points
    36 883
    Par défaut
    Salut,

    Citation Envoyé par RiivaG Voir le message
    Il n'y a pas de moyen d'optimiser un peu plus le temps de traitement ?

    (Je demande ça car j'ai une liste de 10 000 points à traiter, et je travaille dessus actuellement, ça peut prendre pas mal de temps Du coup je cherche à optimiser le plus de temps possible ^^)
    En l'état, vous pouvez juste supprimer l'appel à produitScalaire en incluant le calcul dans la définition du lambda.

    Après vous pouvez décomposer l'opération en deux:
    • calcul des produits scalaires,
    • rangement des points,

    et essayer d'utiliser numpy.dot pour les calculs (être plus efficace) ou les paralléliser (utiliser plus de ressources).

    Après il faut vous poser des questions côté conception: avez vous vraiment besoin de calculer le produit scalaire avec les 10000 points?

    - W

  7. #7
    Membre émérite

    Homme Profil pro
    Ingénieur calcul scientifique
    Inscrit en
    Mars 2013
    Messages
    1 229
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur calcul scientifique

    Informations forums :
    Inscription : Mars 2013
    Messages : 1 229
    Points : 2 328
    Points
    2 328
    Par défaut
    Citation Envoyé par RiivaG Voir le message
    Je vous remercie encore une fois pour votre réponse ! ^^

    Je comprends beaucoup mieux l'utilisation de "operator.itemgetter()".

    Donc si j'ai bien compris, dans le cas présent le mieux reste d'utiliser ce code ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    l.sort( key = lambda x: produitScalaire( u, x))
    Il n'y a pas de moyen d'optimiser un peu plus le temps de traitement ?

    (Je demande ça car j'ai une liste de 10 000 points à traiter, et je travaille dessus actuellement, ça peut prendre pas mal de temps Du coup je cherche à optimiser le plus de temps possible ^^)

    1) Si vous voulez les points relativement à une certaine distance, je me demande pourquoi vous calculez le produit scalaire.... La distance entre 2 points A, et B de coordonnées respectives (xA,yA) et (xB, yB), c'est sqrt((xB-xA)²+(yB-yA)²).

    2) Si vous voulez qqch de rapide, il y a numpy qui est parfaitement adapté pour cela. 10 000 points ce sera instantanné.

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

Discussions similaires

  1. [Toutes versions] Pouvoir utiliser une fonction dans tous mes classeurs Excel
    Par SylvainM dans le forum Macros et VBA Excel
    Réponses: 6
    Dernier message: 27/03/2014, 21h10
  2. Trier une liste avec Collections.sort(liste)
    Par nakry dans le forum Collection et Stream
    Réponses: 18
    Dernier message: 25/09/2013, 15h52
  3. Réponses: 1
    Dernier message: 08/06/2008, 12h15
  4. Changer une fonction qui utilise une liste par un tableau!
    Par sara21 dans le forum Général JavaScript
    Réponses: 1
    Dernier message: 03/05/2007, 13h18

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