Python string.join (Liste) auf Objektarray anstatt auf String-Array


291

In Python kann ich Folgendes tun:

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

Gibt es eine einfache Möglichkeit, dasselbe zu tun, wenn ich eine Liste von Objekten habe?

>>> 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

Oder muss ich auf eine for-Schleife zurückgreifen?

Antworten:


432

Sie können stattdessen ein Listenverständnis oder einen Generatorausdruck verwenden:

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

3
oder ein Generatorausdruck: ',' .join (str (x) für x in Liste)
dF.

1
Irgendeine Idee, welcher von ihnen schneller sein würde?
Gozzilli

Meine Experimente besagen, dass das Listenverständnis bei kleinen Listen gut 60% schneller sein kann (Experiment wird 10 ^ 6 Mal mit einer Liste von drei Objekten ausgeführt). Ihre Leistung ist jedoch auf großen Listen ähnlich (2. Experiment einmal auf einer 10 ^ 7-Objektliste () ausgeführt).
Gozzilli

3
Für eine Beschleunigung von gut 30% (über dem Generatorausdruck oben) kann man den vermeintlich weniger lesbaren mapAusdruck (unten) verwenden.
K3 --- rnc

2
Diese Antwort ist objektiv schlechter als die mapLösung.
PascalVKooten

96

Der integrierte String-Konstruktor ruft automatisch auf obj.__str__:

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

1
map () ändert die Liste nicht, es entspricht [str (o) für o in der Liste]
dF.

11
+1: Karte ist ein guter Ansatz; "Ändern der Liste" ist kein genauer Kommentar.
S.Lott

2
(eine andere) +1 .. Karte ist nicht weniger lesbar, muss nur wissen, was die Kartenfunktion tut
Lapax

1
@ Michael Nicht korrekt. reducewar derjenige, der entfernt wurde, weil es normalerweise Leute erraten ließ und somit nicht "pythonisch" war. mapauf der anderen Seite ist kein Problem.
PascalVKooten

1
(eine andere) +1: Aus der Perl-Welt kommend ist dies die häufigste Sache im Universum: join ("sep", list) - und alle Elemente der Liste werden in ihre String-Darstellungen konvertiert. Ich habe wirklich Mühe gehabt, eine Lösung in Python zu finden.
Jason

2

Eine andere Lösung besteht darin, den Join-Operator der Klasse str zu überschreiben.

Definieren wir eine neue Klasse my_string wie folgt

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

Dann können Sie tun

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

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

print comma.join(list)

und du bekommst

name,name,name

Übrigens, indem Sie list als Variablennamen verwenden, definieren Sie die Listenklasse (Schlüsselwort) neu! Verwenden Sie vorzugsweise einen anderen Bezeichnernamen.

Ich hoffe, Sie finden meine Antwort hilfreich.


Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.