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 :

sorted lambda key suivant chaine [Python 3.X]


Sujet :

Python

  1. #1
    Membre chevronné
    Homme Profil pro
    Enseignant
    Inscrit en
    Juin 2013
    Messages
    1 608
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2013
    Messages : 1 608
    Points : 2 072
    Points
    2 072
    Par défaut sorted lambda key suivant chaine
    Bonjour,
    J'ai un petit souci avec un tri.
    Pour éviter un problème xyz, je présente l'origine de celui-ci.
    J'ai deux fichiers excel dont un qui est à compléter car 3 colonnes manquantes.
    J'ai ces colonnes manquantes mais le problème c'est que celles-ci sont un autre fichier excel dans lequel les nom/prénom sont classés par ordre alphabétiques.
    Donc je veux remettre les colonnes manquantes dans l'ordre de mon premier fichier excel.

    J'ai obtenu des listes pour chaque colonne de mes fichiers excel et j'essaie de reclasser mes listes. Peut-être n'est-ce pas une bonne option mais elle me paraît la plus à ma portée.
    J'ai fait cela, sachant que je veux donc classer liste_nom_prenom_note_p en ayant pour clé les éléments de liste_nom_prenom

    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
    liste_nom = ["BG", "CZ", "AB", "BG", "FT"]
    liste_prenom = ["ab", "dt", "uy", "ir", "ml"]
     
    liste_nom_prenom = zip(liste_nom, liste_prenom)
     
    liste_nom_p = sorted(liste_nom)
    liste_prenom_p = sorted(liste_prenom)
    liste_nom_prenom_p = sorted(liste_nom_prenom)
    liste_n_p = [2,7,5,None,4]
    liste_nom_prenom_note_p = zip(liste_nom_prenom_p,liste_n_p)
     
     
    print(liste_nom)
    print(liste_prenom)
    print(liste_nom_p)
    print(liste_prenom_p)
    print(liste_n_p)
    print("nom_prenom", list(liste_nom_prenom))
    print(liste_nom_prenom_p)
    print(list(liste_nom_prenom_note_p))
    liste_n=sorted(liste_nom_prenom_note_p,key=lambda x: x[liste_nom_prenom])
    print(liste_n)
    Je devrais peut-être commencer par élucider un mystère pour moi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    print("nom_prenom", list(liste_nom_prenom))
    me renvoie une liste vide...
    Pas d'aide par mp.

  2. #2
    Expert éminent
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 461
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 461
    Points : 9 248
    Points
    9 248
    Billets dans le blog
    6
    Par défaut
    Bonjour,

    "zip" est un itérateur. Il faut donc écrire:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    liste_nom_prenom = list(zip(liste_nom, liste_prenom))
    Qui donne:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    [('BG', 'ab'), ('CZ', 'dt'), ('AB', 'uy'), ('BG', 'ir'), ('FT', 'ml')]
    Un expert est une personne qui a fait toutes les erreurs qui peuvent être faites, dans un domaine étroit... (Niels Bohr)
    Mes recettes python: http://www.jpvweb.com

  3. #3
    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,

    Dans votre code, liste_nom_prenom est un generateur: zip(liste_nom, liste_prenom).
    C'est un pistolet à un coup: vous ne pouvez l'exécuter qu'une seule fois... et les fois suivantes, çà retournera une liste vide (tous les items ayant été déjà consommés).

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

  4. #4
    Membre chevronné
    Homme Profil pro
    Enseignant
    Inscrit en
    Juin 2013
    Messages
    1 608
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2013
    Messages : 1 608
    Points : 2 072
    Points
    2 072
    Par défaut
    ok, merci pour cette précision, itérateur est une notion difficile pour moi. Pour le reste, j'attends votre aide.
    Pas d'aide par mp.

  5. #5
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 685
    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 685
    Points : 30 974
    Points
    30 974
    Billets dans le blog
    1
    Par défaut
    Bonjour
    Citation Envoyé par marco056 Voir le message
    itérateur est une notion difficile pour moi
    Pas compliqué: prenons une fonction qui retourne 5 trucs. Un débutant pensera tout naturellement à les retourner d'un coup, soit en liste, soit en tuple (ma préférence quand l'ensemble n'est pas destiné à évoluer) => def fct(): return (1, 2, 3, 4, 5).

    Toutefois il se trouve que dans 99% des cas, l'appelant lui, se servira de ce retour dans une itération pour traiter chaque valeur => for x in fct(): print(x). Et en plus il ne s'en servira qu'une seule fois. Dommage d'avoir donc consommé de la mémoire pour stocker 5 nombres alors qu'on n'en utilise qu'un seul.

    Ok, admettons (c'est pas ça qui va plomber un code quoique... ça+ça+ça... mais ok). Toutefois arrive un autre souci inhérent avec la quantité de valeurs retournées par rapport au temps de traitement. Il est alors possible que la dernière valeur (ici 5) ait perdu sa pertinence du fait du temps de traitement des 4 précédentes.
    Exemple
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    from datetime import *
    import time
     
    def fct(x):
    	ret=[]
    	for i in range(x):
    		ret.append(datetime.today().strftime("%H:%M:%S"))
    	return ret
     
    for (i, f) in enumerate(fct(5), 1):
    	print(i, f)
    	time.sleep(5)
    Dans cet exemple qui prendra 25 secondes pour s'exécuter, on aura 5 fois la même heure. Il est évident que la dernière ligne n'aura pas de rapport avec la réalité (l'heure affichée ne sera plus celle de la réalité).

    Donc on a un souci de "gaspilage" (stocker 5 valeurs pour n'en traiter qu'une seule) et de perte de pertinence à cause du temps de traitement entre la date de création de la valeur et sa date d'utilisation. Un client commande 50 trucs, le programme donne les références prises en bdd, puis un autre client achète le truc en boutique et quand l'employé va le chercher en rayon pour honorer la commande, il n'y est plus.

    C'est là qu'entrent en jeux les générateurs. Ils permettent à la fonction de "générer" la valeur au moment où l'appelant en a réellement besoin. Cela se fait au travers du yield qui renvoie l'info demandée (comme un return) mais qui garde trace de la position du code. Et à l'appel suivant, il reprend de cette position pour générer et renvoyer la valeur suivante.

    Exemple 1
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    def fct():
    	yield 1
    	yield 2
    	yield 3
    	yield 4
    	yield 5

    Du côté appelant, rien ne change. Il peut parfaitement réécrire sa boucle for x in fct(): print(x). Au premier appel, la fonction retourne 1. Au second appel, elle repart du 1 pour continuer son travail et retourne 2 et etc.

    Exemple 2
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    from datetime import *
    import time
     
    def fct(x):
    	for i in range(x):
    		yield datetime.today().strftime("%H:%M:%S")
     
    for (i, g) in enumerate(fct(5), 1):
    	print(i, g)
    	time.sleep(5)
    Ici les heures affichées seront celles du moment réel de l'affichage. Le générateur a résolu tous nos problèmes tout en restant compatible avec l'appelant qui, lui, ne change pas sa façon de faire. Et ça c'est important.

    Seul inconvénient, le générateur ne peut être consommé qu'une seule fois. Si on le stocke qqpart et qu'on tente deux boucles dessus, la seconde ne se fait pas (cela a été ton cas). Mais comme je l'ai dit, dans 99% des cas le générateur n'est utilisé qu'une seule fois et pour le 1% restant (ben toi quoi ) il reste alors la solution de le transformer explicitement en tuple ce qui le fige en reproduisant alors le comportement initial qui n'est alors pas perdu.

    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    def fct1(): return (1, 2, 3, 4, 5)
     
    def fct2():
    	yield 1
    	yield 2
    	yield 3
    	yield 4
    	yield 5
     
    res1=fct1()
    res2=tuple(fct2())
    print(res1, res2, res1 == res2)
    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]

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

Discussions similaires

  1. tri suivant chaine de caractères
    Par cobra02 dans le forum Langage SQL
    Réponses: 1
    Dernier message: 17/03/2011, 09h18
  2. Fonction split() suivant chaine de caracteres
    Par pingouinos_64 dans le forum Collection et Stream
    Réponses: 3
    Dernier message: 02/03/2010, 11h46
  3. Réponses: 3
    Dernier message: 29/01/2007, 15h10
  4. Formatage du chaine suivant un masque
    Par AlexB59 dans le forum Langage
    Réponses: 1
    Dernier message: 07/02/2006, 10h31
  5. langage] Découper une chaine suivant un délimiteur
    Par totox17 dans le forum Langage
    Réponses: 2
    Dernier message: 25/11/2002, 16h25

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