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 :

break et list comprehension ?


Sujet :

Python

  1. #1
    Expert confirmé Avatar de PauseKawa
    Homme Profil pro
    Technicien Help Desk, maintenance, réseau, système et +
    Inscrit en
    Juin 2006
    Messages
    2 725
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Technicien Help Desk, maintenance, réseau, système et +
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 725
    Points : 4 005
    Points
    4 005
    Par défaut break et list comprehension ?
    Bonjour,

    Question purement théorique.
    Auriez vous une idée pour utiliser un break sur une condition if dans une list compréhension ?
    Un exemple
    Soit le liste l
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    l = [0, 1, 0, 1, 1, 0, 1, 1, 1, 1]
    Et le code suivant
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    for e in l:
        if e == 0:
            l.remove(e)
    Qui est traduisible comme ceci
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    [l.remove(e) for e in l if e==0]
    (Je note bien la modification de la liste lors de son itération. .remove(item) supprimant le premier élément trouvé pas de problème ici)
    Comment traduire (est ce possible ?) ceci
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    for e in l:
        if e == 0:
            l.remove(e)
        if 0 not in l:
            break
    (Soit en gros
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    while 0 in l: l.remove(0)
    mais avec une list compréhension)

    Merci

    @+
    Merci d'utiliser le forum pour les questions techniques.

  2. #2
    Membre expérimenté
    Avatar de Luke spywoker
    Homme Profil pro
    Etudiant informatique autodidacte
    Inscrit en
    Juin 2010
    Messages
    1 077
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Etudiant informatique autodidacte

    Informations forums :
    Inscription : Juin 2010
    Messages : 1 077
    Points : 1 742
    Points
    1 742
    Par défaut
    Une liste de compréhension renvoie une liste qui subit un traitement d'après les structures conditionnelles quelle contient donc il faut lui affecter une variable qui contiendra le résultat du traitement de la liste de compréhension:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    >>>l = [0, 1, 0, 1, 1, 0, 1, 1, 1, 1]
    >>>while 0 in l :
           a=[l.remove(e) for e in l if e == 0] 
           if not a.__contains__(0) :
             break 
    >>>l
    >>>[1, 1, 1, 1, 1, 1, 1]
    Je sais pas si c'est ca que tu voulais faire.
    Pour faire tes armes:
    Use du présent pour construire ton futur sinon use de ce que tu as appris auparavant.
    Et sois toujours bien armé avant de te lancer.
    Le hasard ne sourit qu'aux gens préparés...
    Site: Website programmation international (www.open-source-projects.net)
    Site: Website imagerie 3D (www.3dreaming-imaging.net)
    Testez aux moins pendant une semaine l'éditeur avec terminaux intégrées it-edit Vous l'adopterai sûrement !
    FUN is HARD WORK !!!

  3. #3
    Membre éprouvé

    Homme Profil pro
    Diverses et multiples
    Inscrit en
    Mai 2008
    Messages
    662
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Diverses et multiples

    Informations forums :
    Inscription : Mai 2008
    Messages : 662
    Points : 1 273
    Points
    1 273
    Par défaut
    A mon humble avis, c’est tout simplement impossible… La syntaxe des comrehensions, pour puissante qu’elle soit, a tout de même ses limites.

    Et puis, j’ai quand même l’impression que tu en abuses déjà pas mal, là, non*?

    Quand je vois*:

    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    [l.remove(e) for e in l if e==0]

    …honnêtement, je frémis*!

    Certes, ça marche et fait (à peu près, essaye avec plusieurs 0 de suite pour voir) ce que tu veux, mais ce n’est pas ce pour quoi ont été conçues les comprehensions, il me semble bien plus sage ici d’en rester aux boucles classiques*! Après, si tu veux t’amuser, évidemment…

  4. #4
    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
    Je suis tout à fait d'accord avec mont29; une list comprehension est une expression et il vaut mieux la traiter comme tel.
    Par exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    l = [e for e in l if e != 0]
    Bien sûr ça ne fait pas la même chose que ton code, la liste n'est pas modifiée en place, et s'il existait d'autres références à la liste d'origine, celles-ci pointeront toujours sur l'ancienne liste qui n'est pas modifiée. Mais au niveau des performances, ce sera sans doute plus efficace, car remove peut être assez couteux vu qu'il doit faire une recherche et décaler tous les éléments qui suivent vers la gauche...

    [Edit]: suppression grosses bêtises.

    C'est généralement une mauvaise idée de modifier un container sur lequel on est en train d'itérer. Comme le dit mont29, si tu as deux 0 de suite dans la liste, le second ne sera pas supprimé, car remove va supprimer le premier, ce qui décalera tout le reste de la liste d'une position vers la gauche, et l'itération suivante sautera au-dessus de l'élement qui suit celui qui vient d'être supprimé. L'itérateur de liste ne fait pas une copie de la liste à son initialisation.

    Il y a un tas de solutions possibles, par 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
    17
    18
    19
     
    # solution 1
    for i in range(l.count(0)):
        l.remove(0)
     
    # solution 2
    try:
        while 1:
            l.remove(0)
    except ValueError:
        pass
     
    # solution 3
    i = 0
    while i < len(l):
        if l[i] == 0:
            del l[i]    # plus efficace que remove si on connait l'indice
        else:
            i = i+1    # on n'incrémente i que si on n'a rien supprimé

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

    Je n'ai pas compris ce que voulait faire PauseKawa et comme l'exemple proposé ne me motive pas pour passer par une list compréhension...
    Je ne sais pas.

    Pour l'instant, j'ai compris: "on veut modifier la liste" in place pour éviter que les variables pointant vers cette liste loupent sa modification.

    Lorsqu'on écrit:
    L = [0, 1, 0, 1]
    "L" est une variable dans l'espace de nom courant à laquelle on a assigné la liste [0, 1, 0, 1]. La liste est une boîte de type "container". Autrement dit boîte et contenu sont "différents" - avec un entier boite et contenu sont "identiques".
    L est une variable qui pointe sur la "boîte".

    Pratiquement, il est possible de faire:
    L = [e for e in L if e != 0], ou
    L[:] = [e for e in L if e != 0]
    et çà ne fait pas la même chose.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    >>> L = [0, 1, 0, 1] # initialisation de L a l'adresse d'une liste contenant...
    >>> R = L  # R pointe vers la même chose que L
    >>> R # contrôle:
    [0, 1, 0, 1]
    >>> L[:] = [ x for x in L if x != 0 ] # on remplace le contenu de la liste
    >>> R # la référence "suit"...
    [1, 1]
    >>> L = [0, 1, 0, 1] # on colle a L une autre boîte...
    >>> R # dans ce cas, le contenu de a reste inchangé.
    [1, 1]
    >>>
    Hmm. Pour l'instant, pas besoin de passer par .remove pour changer l'ensemble du contenu de la liste.
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  6. #6
    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
    Bien vu wiztricks,
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    L[:] = [ x for x in L if x != 0 ]
    Ce n'est pas tout à fait une modification "en place", mais l'effet est le même, et c'est plus simple et plus efficace.

    Je n'avais pas remarqué que le PO était PauseKawa; j'aurais répondu un peu différemment si je l'avais remarqué...

    L'exemple est mal choisi, mais la question est intéressante à un niveau plus général. Je dirais que non, il n'est pas possible de "sortir d'une list comprehension avant la fin", mais on peut inventer des trucs un peu tordus:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    def break_iterator(iterable, cond):
            for e in iter(iterable):
                if cond(e): break
                yield e
     
    # reproduit l'exemple original (avec la même erreur)
    l = [0, 1, 0, 1, 1, 0, 1, 1, 1, 1]
     
    [l.remove(e) for e in break_iterator(l, lambda _: 0 not in l) if e == 0]
     
    print l
    [EDIT:] En fait, il existe un générateur similaire dans la librairie standard: itertools.takewhile.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    from itertools import takewhile
     
    # reproduit l'exemple original avec la même erreur
    l = [0, 1, 0, 1, 1, 0, 1, 1, 1, 1]
     
    [l.remove(e) for e in takewhile(lambda _: 0 in l, l) if e == 0]
     
    print l

  7. #7
    Expert confirmé Avatar de PauseKawa
    Homme Profil pro
    Technicien Help Desk, maintenance, réseau, système et +
    Inscrit en
    Juin 2006
    Messages
    2 725
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Technicien Help Desk, maintenance, réseau, système et +
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 725
    Points : 4 005
    Points
    4 005
    Par défaut
    Désolé pour le retard (et l'exemple bidon (remove dans un for... , et dire que je mets en garde sur la chose il y a quelques sujets de là...)) et merci pour vos participations.

    C'est bien le sens de la question (inutile il est vrais, mais intéressante non ?) dividee
    L'utilisation de for pose encore problème* mais c'est bien dans ce sens que je dois chercher il me semble.
    A vrais dire dans le sens [e for e in l if e == 0] et avec le (joli) jeu de boite de wiztricks cela devrais passer.

    @+

    *
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    def break_iterator(iterable, cond):
            for e in iter(iterable):
                if cond(e): break
                yield e
     
    l = [0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1]
    [l.remove(e) for e in break_iterator(l, lambda _: 0 not in l) if e == 0]
     
    print l
    output
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    [1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1]
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    l = [0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1]
    from itertools import takewhile
     
    [l.remove(e) for e in takewhile(lambda _: 0 in l, l) if e == 0]
     
    print l
    output
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    [1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1]
    Merci d'utiliser le forum pour les questions techniques.

  8. #8
    Expert confirmé Avatar de PauseKawa
    Homme Profil pro
    Technicien Help Desk, maintenance, réseau, système et +
    Inscrit en
    Juin 2006
    Messages
    2 725
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Technicien Help Desk, maintenance, réseau, système et +
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 725
    Points : 4 005
    Points
    4 005
    Par défaut
    C'est bien cela: l'itérable n'as pas besoin d’être la liste.
    Merci pour vos réponses, excellentes pour ne pas changer

    @+
    Merci d'utiliser le forum pour les questions techniques.

  9. #9
    Membre éprouvé
    Inscrit en
    Août 2010
    Messages
    1 124
    Détails du profil
    Informations forums :
    Inscription : Août 2010
    Messages : 1 124
    Points : 1 277
    Points
    1 277
    Par défaut
    Je vois 2 solutions basée sur les exceptions:

    */ celle de Dividee: l'itérateur break sur une sentinelle. On perd la vitesse C de certains iterateurs. De plus, la sentinelle me semble plus liée à la fonction qu'à l'itérateur
    */ Une autre, ou c'est la fonction mappée qui lève une exception (code non testé, pas de python sur ce poste dsl). On garde la rapidité de l'itérateur, mais on perds en vitesse si la fonction mappée est built-in.

    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
     
    """ From http://code.activestate.com/recipes/204297-the-secret-name-of-list-comprehensions/ """
    def thislist():
        """Return a reference to the list object being constructed by the
        list comprehension from which this function is called. Raises an
        exception if called from anywhere else.
        """
        import sys
        d = sys._getframe(1).f_locals
        nestlevel = 1
        while '_[%d]' % nestlevel in d:
            nestlevel += 1
        return d['_[%d]' % (nestlevel - 1)].__self__
    class LCstop(Exception):pass
    def f(x):
        if x==0: raise LCstop()
        else : return x+1
    try: l= [f(x) for x in [1,2,3,0,1,2,3]]
    except LCstop: l= thislist()
    except:raise

  10. #10
    Expert confirmé Avatar de PauseKawa
    Homme Profil pro
    Technicien Help Desk, maintenance, réseau, système et +
    Inscrit en
    Juin 2006
    Messages
    2 725
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Technicien Help Desk, maintenance, réseau, système et +
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 725
    Points : 4 005
    Points
    4 005
    Par défaut
    Taper dans la frame ? Pourquoi ?
    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
    class break_iterator:
        def __init__(self, iterobj, cond):
            self.iterobj = l
            self.cond = cond
            self.high = len(l) - 1
     
        def __iter__(self):
            self.current = -1
            return self
     
        def __next__(self):
            self.current += 1
            if self.current > self.high or self.cond(self.iterobj[self.current]):
                raise StopIteration
            else:
                return self.iterobj[self.current]
     
        next = __next__
     
    l = [0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 5, 0, 0, 1, 0, 5, 1, 1, 1, 0, 0]
    l[:] = [e for e in break_iterator(l, lambda _: _ == 5) if e == 0]
    print(l)
    Merci d'utiliser le forum pour les questions techniques.

  11. #11
    Expert confirmé Avatar de PauseKawa
    Homme Profil pro
    Technicien Help Desk, maintenance, réseau, système et +
    Inscrit en
    Juin 2006
    Messages
    2 725
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Technicien Help Desk, maintenance, réseau, système et +
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 725
    Points : 4 005
    Points
    4 005
    Par défaut
    Bonjour VV33D,

    Je viens de regarder ton seconde solution.
    '_[%d]' % nestlevel ne fonctionne pas en Python 3. A partir de la autant utiliser ce qui en d est présent en Python 2 et 3, f par exemple.
    Mais si l'on utilise f pourquoi ne pas le faire directement ? Le read only ? Pas de souci puisque ce que l'on souhaite c'est justement une lecture.
    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
    class LCstop(Exception):
        pass
     
    def thislist(f):
        if hasattr(f, 'func_defaults'):
            return f.func_defaults[0]
        elif hasattr(f, '__defaults__'):
            return f.__defaults__[0]
        else:
            # Gloups...
            return []
     
    def f(x, cond, local=[], tempo=[]):
        if x == cond:
            local[:] = tempo # Ecrase local donc pas besoin de le vider.
            del tempo[:] # Lui oui par contre.
            raise LCstop()
        else:
            tempo.append(x)
            return x
     
    l = [0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 5, 0, 0, 1, 0, 5, 1, 1, 1, 0, 0]
    cond = 5
    try:
        [f(x, cond) for x in l if x in (0, cond)]
    except LCstop:
        l[:] = thislist(f)
    print(l)
    try:
        [f(x, 5) for x in l if x in (0, 5)]
        # x == 0 or x == cond ? in plus rapide ?
    except LCstop:
        l[:] = thislist(f)
    print(l)
    @+

    Edit: J'avais oublier une réponse.
    Citation Envoyé par mont29 Voir le message
    Et puis, j’ai quand même l’impression que tu en abuses déjà pas mal, là, non*?
    La réponse est:
    Citation Envoyé par dividee Voir le message
    Je n'avais pas remarqué que le PO était PauseKawa; j'aurais répondu un peu différemment si je l'avais remarqué...
    ...mais on peut inventer des trucs un peu tordus
    @++
    Merci d'utiliser le forum pour les questions techniques.

  12. #12
    Expert confirmé Avatar de PauseKawa
    Homme Profil pro
    Technicien Help Desk, maintenance, réseau, système et +
    Inscrit en
    Juin 2006
    Messages
    2 725
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Technicien Help Desk, maintenance, réseau, système et +
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 725
    Points : 4 005
    Points
    4 005
    Par défaut
    Bonjour,

    Grosse bêtise dans mon code...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    l = [0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 5, 0, 0, 1, 0, 6, 1, 1, 1, 0, 0]
    cond = 5
    try:
        [f(x, cond) for x in l if x in (0, cond)]
    except LCstop:
        l[:] = thislist(f)
    print(l)
    l = [0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 5, 0, 0, 1, 0, 6, 1, 1, 1, 0, 0] # <<<
    try:
        [f(x, 6) for x in l if x in (1, 6)]
    except LCstop:
        l[:] = thislist(f)
    print(l)
    @+
    Merci d'utiliser le forum pour les questions techniques.

  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
    Autant je peux apprécier cette jonglerie avec la machinerie interne de CPython, autant je souhaite ardemment que thislist reste reléguée au musée des curiosités Python et ne trouve jamais son chemin dans le vaste monde

  14. #14
    Expert confirmé Avatar de PauseKawa
    Homme Profil pro
    Technicien Help Desk, maintenance, réseau, système et +
    Inscrit en
    Juin 2006
    Messages
    2 725
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Technicien Help Desk, maintenance, réseau, système et +
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 725
    Points : 4 005
    Points
    4 005
    Par défaut
    Et bien que la question soit purement théorique, sur un sujet bien limité, c'est sans aucun doute pourquoi j'ai hésiter a poster ma réponse...
    Je me joins à dividee dans sa demande, du Python 'propre'.
    Merci d'utiliser le forum pour les questions techniques.

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

Discussions similaires

  1. Iterator over lists comprehensions ?
    Par ®om dans le forum Général Python
    Réponses: 3
    Dernier message: 27/09/2011, 23h47
  2. List comprehension ou boucle for?
    Par Gui13 dans le forum Général Python
    Réponses: 10
    Dernier message: 07/06/2010, 08h52
  3. probleme de comprehension des listes
    Par marsafari dans le forum Général Python
    Réponses: 2
    Dernier message: 29/07/2009, 15h37
  4. requête insert et comprehension list
    Par polo42 dans le forum Général Python
    Réponses: 5
    Dernier message: 17/05/2008, 10h48
  5. Copier un dictionnaire par une list comprehension
    Par Sve@r dans le forum Général Python
    Réponses: 6
    Dernier message: 12/05/2008, 10h25

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