Bienvenue sur IndexError.

Ici vous pouvez poser des questions sur Python et le Framework Django.

Mais aussi sur les technos front comme React, Angular, Typescript et Javascript en général.

Consultez la FAQ pour améliorer vos chances d'avoir des réponses à vos questions.

Liste d'objets vers string

+3 votes

Je souhaiterais tranformer une liste du genre ["aaa", ("b", "c"), (2, "3p", "x"), 11] en "aaa-b-c-2-3p-x-11". Tous les objets ont une méthode __str__.

Existe-t-il une manière simple de faire cela ou vais-je devoir me farcir des for et des if à la pelle ?

demandé 1-Mar-2015 par Vayel (1,050 points)

2 Réponses

+5 votes
 
Meilleure réponse

Tu peux utiliser cette fonction:

def srepr(arg):
    if isinstance(arg, basestring): # Python 3: isinstance(arg, str)
        return repr(arg)
    try:
        return "-".join(srepr(x) for x in arg)
    except TypeError: # catch when for loop fails
        return repr(arg) # not a sequence so just return repr

Source: http://stackoverflow.com/a/1835259

Je vois pas comment éviter des if / for

répondu 1-Mar-2015 par naingenieu
sélectionné 4-Mar-2015 par Vayel

Je préfère cette solution à celle de bulange.

  • pour tester un type, c'est mieux de le faire par "isinstance" que par "type() =="

  • on essaie d'itérer sur l'argument sans se poser de question de ce que c'est réellement. C'est plus pythonique (duck typing). Et ça permet de prendre en compte les tuples, les listes et plein d'autres trucs.

recher> oui tu as raison, c'est plus générique et élégant. :)

+2 votes

Il y a peut-être plus élégant, mais comme ta liste n'est pas "uniforme" (elle contient des tuples, ou des objets simples...), je me ferai mon propre générateur "chain" (en référence à celui d'itertools).
Un truc comme ça:

def mon_chain_a_moi(*args):
    for sub in args:  # pour chaque élément
        if type(sub) == tuple:  # si c'est un tuple, je continue à itérer
            for e in sub:
                yield e  # et je renvoie l'élément du tuple
        else:
            yield sub  # si c'est pas un tuple alors je le renvoie comme ça

Et je l'utiliserai comme ça:

l = ["aaa", ("b", "c"), (2, "3p", "x"), 11]  # ta liste
out = '-'.join([str(e) for e in mon_chain_a_moi(*l)])  # un join avec un appel à str() sur chaque élément renvoyé par le générateur
print(out)  # aaa-b-c-2-3p-x-11
répondu 1-Mar-2015 par bulange (618 points)
...