Konvertieren Sie eine Liste von Zeichen in eine Zeichenfolge

414

Wenn ich eine Liste mit Zeichen habe:

a = ['a','b','c','d']

Wie konvertiere ich es in eine einzelne Zeichenfolge?

a = 'abcd'
nr
quelle
7
Link in eine andere Richtung
Tobias Kienzler

Antworten:

584

Verwenden Sie die joinMethode der leeren Zeichenfolge, um alle Zeichenfolgen zusammen mit der leeren Zeichenfolge dazwischen zu verbinden:

>>> a = ['a', 'b', 'c', 'd']
>>> ''.join(a)
'abcd'
Daniel Stutzbach
quelle
1
Wie kann ich Leerzeichen zwischen den Zeichen einfügen? trotzdem, um es zu tun, ohne das Ganze zu durchlaufen?
Clifgray
18
tun Sie einfach ' '.join(list)mit einem Leerzeichen zwischen den Anführungszeichen
Clifgray
Eine schöne Sache dabei ist, dass Sie '\ n'.join (a) verwenden können, wenn Sie eine Liste in einen Text mit neuen Zeilen für jedes Element schreiben möchten
Norfeldt
28
Zur Verdeutlichung: "".join(['a','b','c'])bedeutet Join all elements of the array, separated by the string "". In gleicher Weise " hi ".join(["jim", "bob", "joe"])wird erstellt "jim hi bob hi joe".
Jack
39

Dies funktioniert in vielen gängigen Sprachen wie JavaScript und Ruby. Warum nicht in Python?

>>> ['a', 'b', 'c'].join('')
Traceback (most recent call last):
   File "<stdin>", line 1, in <module>
AttributeError: 'list' object has no attribute 'join'

Seltsamerweise befindet sich die joinMethode in Python in der strKlasse:

# this is the Python way
"".join(['a','b','c','d'])

Warum joinist eine Methode im listObjekt nicht wie in JavaScript oder anderen gängigen Skriptsprachen? Dies ist ein Beispiel dafür, wie die Python-Community denkt. Da join eine Zeichenfolge zurückgibt, sollte diese in der Zeichenfolgenklasse und nicht in der Listenklasse platziert werden. Die str.join(list)Methode bedeutet also: Verknüpfen Sie die Liste mit einer neuen Zeichenfolge strals Trennzeichen (in diesem Fall strhandelt es sich um eine leere Zeichenfolge).

Irgendwie habe ich diese Art zu denken nach einer Weile geliebt. Ich kann mich über viele Dinge im Python-Design beschweren, aber nicht über dessen Kohärenz.

Paulo Scardine
quelle
1
Der Hauptgrund dafür, dass der Join eher eine Zeichenfolgenmethode als eine Listenmethode ist, besteht darin, dass er jede iterierbare Methode akzeptiert , nicht nur eine Liste. Sie können Generatorausdrücke, Wörterbücher, Mengen, Ansichten verschiedener Art usw. verwenden. Daher ist es in den meisten Sprachen viel flexibler als die Array-Join-Operation.
Rosuav
Ich habe Pythons string.join()mit den meisten Sammlungen verglichen , die eine join()Methode in vielen dynamischen Sprachen haben. In Bezug auf iterables ist es für solche Sprachen wahrscheinlich kein Problem, da es genauso einfach (und lesbar) ist, das iterable in einen Sammlungskonstruktor und eine Kette in die join()Methode einzuschließen .
Paulo Scardine
Ja, vorausgesetzt, sie haben entweder faule Listen (Haskell-Stil) oder Sie können die Liste vor dem Start problemlos im Speicher zusammenführen. Mein Punkt ist, dass Pythons Vorgehensweise nicht willkürlich ist, sondern eine sehr gute Rechtfertigung hat.
Rosuav
1
Es ist nicht willkürlich, es ist eine Entwurfsentscheidung, die Verschmutzung von Namespaces in jeder Klasse zu vermeiden. :-)
Paulo Scardine
Genau. Außerdem sind nicht alle diese Klassen - "iterable" ist ein Protokoll, keine Klasse. Sie können mit jeder iterierbaren Datei filtern, zuordnen, verknüpfen usw.
Rosuav
15

Wenn Ihr Python-Interpreter alt ist (z. B. 1.5.2, wie es bei einigen älteren Linux-Distributionen üblich ist), steht Ihnen möglicherweise kein join()altes Zeichenfolgenobjekt als Methode zur Verfügung, und Sie müssen stattdessen das Zeichenfolgenmodul verwenden. Beispiel:

a = ['a', 'b', 'c', 'd']

try:
    b = ''.join(a)

except AttributeError:
    import string
    b = string.join(a, '')

Die Zeichenfolge bwird sein 'abcd'.

Kyle
quelle
10

Dies kann der schnellste Weg sein:

>> from array import array
>> a = ['a','b','c','d']
>> array('B', map(ord,a)).tostring()
'abcd'
Bigeagle
quelle
4
@WinstonEwert Ja, gestern habe ich ein Programm geschrieben, das so etwas tun muss, und ich habe ein paar Möglichkeiten für die Leistung dieser ''.join(['a','b','c'])
Zeilenzählungen
2
Meine eigenen Benchmark-Shows werden siebenmal schneller. pastebin.com/8nSc5Ek1 . Haben Sie etwas dagegen, Ihren Benchmark zu teilen?
Winston Ewert
1
@ WinstonEwert Du hast recht. Ich habe den Grund dafür gefunden: In meinem Programm erhalte ich eine Liste von int aus dem Netzwerk und konvertiere sie dann in einen String, wo dies map(ord,a)nicht erforderlich ist, aber Join-Anforderungen map(chr,a). Hier ist meine Benchmark pastebin.com/1sKFm8ma
bigeagle
15
Vorzeitige Optimierung. Das ist so schwer zu lesen und zu verstehen, was los ist. Sofern der Benutzer keine Leistung in der Operation benötigt, ist eine einfache ''.join()viel besser lesbar.
Luiz Damim
5
nicht einverstanden - Programmierer müssen die schnellsten Methoden für solche Dinge im Auge behalten. Eine einzige einfache Operation, die etwas länger dauert, ist keine große Sache. Auf diese Weise wird jedoch fast jedes geschriebene Programm aufgebläht und nimmt zu viele Ressourcen in Anspruch. Wenn wir uns nicht angewöhnen, die Dinge so schlank wie möglich zu gestalten, haben wir eine Welt, die wie ... nun, wie Windows Vista oder Upstart unter Linux sind gute Beispiele für viele kleine Verknüpfungen, die dazu führen "Aufblähen und schweben", wie tot im Wasser. Sie sind beide auch hässlich. Warum nicht str (). join (a) verwenden, was zu 100% ausdrucksstark ist?
osirisgothra
4

Die Reduktionsfunktion funktioniert auch

import operator
h=['a','b','c','d']
reduce(operator.add, h)
'abcd'
cce
quelle
1
Es nervt mich immer, dass die Betreiber selbst keine erstklassigen Bürger sind. Im Schema wäre das zum Beispiel (reduzieren + h)
Brian Minton
Im Schema (reduce + '' h)oder (apply + h)würde funktionieren. Andererseits benötigt der Add-Operator in Python genau zwei Operanden, weshalb eine Reduzierung erforderlich ist. Andernfalls könnten Sie dies tun operator.add(*h), da applydies in Python offiziell zugunsten der erweiterten Aufrufsyntax (auch bekannt als en.wikipedia.org/wiki/Variadic_function ) veraltet ist
Brian Minton
3

Wenn die Liste Zahlen enthält, können Sie map()mit verwenden join().

Z.B:

>>> arr = [3, 30, 34, 5, 9]
>>> ''.join(map(str, arr))
3303459
yask
quelle
es ist tatsächlich pythonischer zu benutzen''.join([str(i) for i in arr])
user1767754
@ user1767754 Nun, Guido bevorzugt diesen Stil, aber es ist absolut nichts Falsches daran, die Kartenfunktion zu verwenden.
Itsbruce
2
h = ['a','b','c','d','e','f']
g = ''
for f in h:
    g = g + f

>>> g
'abcdef'
Rechnung
quelle
6
Das wäre ziemlich langsam. Die Verwendung ''.join(h)würde Ihre Einzelanhängungsmethode bei weitem übertreffen.
Martijn Pieters
1
In der Python-Bibel (über 1400 Seite 1) heißt es an vielen Stellen, dass dies falsch ist und nach Möglichkeit vermieden werden sollte. Es ist auch ein schmerzlich offensichtliches Markenzeichen des nicht informierten Python-Anfängers (um die Funktionalität nicht zu beleidigen ... nun ja), es mag funktionieren, aber Sie werden von ungefähr 5000 Leuten hören, dass Sie dies nicht tun.
Osirisgothra
2

Außerdem str.joinbesteht die natürlichste Möglichkeit darin, alle Elemente auf einmal zu verwenden io.StringIOund zu missbrauchen writelines:

import io

a = ['a','b','c','d']

out = io.StringIO()
out.writelines(a)
print(out.getvalue())

Drucke:

abcd

Wenn Sie diesen Ansatz mit einer Generatorfunktion oder einer Iterable verwenden, die keine tupleoder keine ist list, wird die temporäre Listenerstellung gespeichert, joinmit der die richtige Größe auf einmal zugewiesen wird (und eine Liste mit 1-Zeichen-Zeichenfolgen ist speichermäßig sehr teuer ).

Wenn Sie wenig Speicher haben und ein träge ausgewertetes Objekt als Eingabe haben, ist dieser Ansatz die beste Lösung.

Jean-François Fabre
quelle
0

Sie könnten auch so verwenden operator.concat():

>>> from operator import concat
>>> a = ['a', 'b', 'c', 'd']
>>> reduce(concat, a)
'abcd'

Wenn Sie Python 3 verwenden, müssen Sie Folgendes voranstellen:

>>> from functools import reduce

da das eingebaute reduce()aus Python 3 entfernt wurde und nun in lebt functools.reduce().

Tonechas
quelle