Python string.join (list) sur un tableau d'objets plutôt que sur un tableau de chaînes


291

En Python, je peux faire:

>>> list = ['a', 'b', 'c']
>>> ', '.join(list)
'a, b, c'

Existe-t-il un moyen simple de faire de même lorsque j'ai une liste d'objets?

>>> class Obj:
...     def __str__(self):
...         return 'name'
...
>>> list = [Obj(), Obj(), Obj()]
>>> ', '.join(list)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: sequence item 0: expected string, instance found

Ou dois-je recourir à une boucle for?

Réponses:


432

Vous pouvez utiliser une compréhension de liste ou une expression de générateur à la place:

', '.join([str(x) for x in list])  # list comprehension
', '.join(str(x) for x in list)    # generator expression

3
ou une expression de générateur: ',' .join (str (x) pour x dans la liste)
dF.

1
une idée sur lequel d'entre eux serait plus rapide?
gozzilli

Mes expériences indiquent que la compréhension de la liste peut être 60% plus rapide sur de petites listes (expérience exécutée 10 ^ 6 fois sur une liste de trois objets). Cependant, leurs performances sont similaires sur de grandes listes (2e expérience exécutée une fois sur une liste de 10 ^ 7 objets ()).
gozzilli

3
pour une bonne accélération de 30% (au-dessus de l'expression du générateur ci-dessus), on peut utiliser l' mapexpression soi-disant moins lisible (ci-dessous).
K3 --- rnc

2
Cette réponse est objectivement pire que la mapsolution.
PascalVKooten

96

Le constructeur de chaîne intégré appellera automatiquement obj.__str__:

''.join(map(str,list))

1
map () ne change pas la liste, c'est équivalent à [str (o) pour o dans la liste]
dF.

11
+1: la carte est une bonne approche; "changer la liste" n'est pas un commentaire précis.
S.Lott

2
(un autre) +1 .. la carte n'est pas moins lisible, il suffit de savoir ce que fait la fonction de carte
lapax

1
@Michael Pas correct. reduceétait celle qui avait été supprimée, car elle laissait généralement les gens deviner et n'était donc pas "pythonique". mapd'autre part n'est pas un problème.
PascalVKooten du

1
(un autre) +1: venant du monde Perl, c'est la chose la plus courante dans l'univers: join ("sep", list) - et tous les éléments de list sont convertis en leurs représentations de chaînes. J'ai vraiment du mal à trouver une solution en python.
Jason

2

une autre solution consiste à remplacer l'opérateur de jointure de la classe str.

Définissons une nouvelle classe my_string comme suit

class my_string(str):
    def join(self, l):
        l_tmp = [str(x) for x in l]
        return super(my_string, self).join(l_tmp)

Ensuite, vous pouvez faire

class Obj:
    def __str__(self):
        return 'name'

list = [Obj(), Obj(), Obj()]
comma = my_string(',')

print comma.join(list)

et vous obtenez

name,name,name

BTW, en utilisant list comme nom de variable, vous redéfinissez la classe list (mot-clé)! Utilisez de préférence un autre nom d'identifiant.

J'espère que vous trouverez ma réponse utile.


En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.