Konwertuj listę znaków na ciąg


Odpowiedzi:


585

Użyj joinmetody pustego ciągu, aby połączyć wszystkie ciągi razem z pustym ciągiem pomiędzy nimi, tak jak poniżej:

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

1
jak mogę dodać spacje między postaciami? w każdym razie zrobić to bez iteracji?
clifgray

18
po prostu zrób ' '.join(list)spację między cytatami
clifgray

Fajną rzeczą w tym jest to, że możesz użyć '\ n'.join (a), jeśli chcesz napisać listę do txt z nowymi wierszami dla każdego elementu
Norfeldt

28
Wyjaśnienie: "".join(['a','b','c'])oznacza Join all elements of the array, separated by the string "". W ten sam sposób " hi ".join(["jim", "bob", "joe"])stworzy "jim hi bob hi joe".
Jack

39

Działa to w wielu popularnych językach, takich jak JavaScript i Ruby, dlaczego nie w Pythonie?

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

Dziwne, w Pythonie join metoda jest na strklasie:

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

Dlaczego join nie ma metody wlist obiekcie jak w JavaScript lub innych popularnych językach skryptowych? Jest to jeden przykład tego, jak myśli społeczność Python. Ponieważ funkcja złączenia zwraca łańcuch, powinna zostać umieszczona w klasie łańcucha, a nie w klasie listy, więc str.join(list)metoda oznacza: połącz listę w nowy ciąg, używając strjako separatora (w tym przypadku strjest to ciąg pusty).

Po jakimś czasie pokochałem ten sposób myślenia. Mogę narzekać na wiele rzeczy w projekcie Pythona, ale nie na jego spójność.


1
Głównym powodem przyłączenia się do metody łańcuchowej zamiast metody listowej jest to, że akceptuje ona dowolną iterowalną , a nie tylko listę. Możesz używać wyrażeń generatora, słowników, zestawów, widoków różnego rodzaju i tak dalej. Jest więc o wiele bardziej elastyczny niż operacja łączenia macierzy w większości języków.
rosuav,

Porównywałem Pythona string.join()z większością kolekcji posiadających join()metodę w wielu dynamicznych językach. Jeśli chodzi o iterable, wydaje mi się, że nie jest to problemem dla takich języków, ponieważ tak łatwe (i czytelne) jest zamknięcie iterowalnego konstruktora kolekcji i łańcucha w join()metodzie.
Paulo Scardine,

Tak, zakładając, że albo mają leniwe listy (w stylu Haskella), albo czujesz się swobodnie, łącząc listę z pamięcią przed rozpoczęciem. Chodzi mi o to, że sposób działania Pythona nie jest arbitralny, ma bardzo dobre uzasadnienie.
rosuav

1
To nie jest arbitralne, to decyzja projektowa, aby uniknąć zanieczyszczenia przestrzeni nazw w każdej klasie. :-)
Paulo Scardine

Dokładnie. Ponadto nie wszystkie z nich są nawet klasami - „iterowalny” to protokół, a nie klasa. Możesz filtrować, mapować, dołączać itp., Używając dowolnej iterowalnej.
rosuav,

15

Jeśli twój interpreter Pythona jest stary (na przykład 1.5.2, który jest powszechny w niektórych starszych dystrybucjach Linuksa), możesz nie mieć join()dostępnej metody dla dowolnego starego obiektu łańcucha, a zamiast tego będziesz musiał użyć modułu łańcucha. Przykład:

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

try:
    b = ''.join(a)

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

Ciąg bbędzie 'abcd'.


10

To może być najszybszy sposób:

>> from array import array
>> a = ['a','b','c','d']
>> array('B', map(ord,a)).tostring()
'abcd'

4
@WinstonEwert tak, wczoraj pisałem program, który musi zrobić coś takiego, a ja odwzorować kilka sposobów na wykonanie tej linii liczy się w moim programie, pokazuje wynik jest o 20% szybszy''.join(['a','b','c'])
bigeagle

2
Moje własne testy porównawcze łączą się 7 razy szybciej. pastebin.com/8nSc5Ek1 . Masz ochotę udostępnić swój punkt odniesienia?
Winston Ewert

1
@WinstonEwert Masz rację. Znalazłem przyczynę tego: w moim programie odzyskuję listę int z sieci, a następnie przekształcam na ciąg znaków, gdzie map(ord,a)jest to niepotrzebne, ale dołączenie wymaga map(chr,a). Oto mój test pastebin.com/1sKFm8ma
bigeagle

15
Przedwczesna optymalizacja. Trudno to przeczytać i zrozumieć, co się dzieje. O ile użytkownik NIE POTRZEBUJE wydajności działania, prosty ''.join()jest o wiele bardziej czytelny.
Luiz Damim

5
nie zgadzam się - programiści muszą pamiętać o najszybszych metodach takich rzeczy. pojedyncza prosta operacja, która trwa trochę dłużej, nie jest niczym wielkim. Jednak w ten sposób prawie każdy napisany program kończy się wzdęciem i zajmuje zbyt wiele zasobów. Kiedy nie mamy zwyczaju robić rzeczy tak odchudzonych, jak to możliwe, powstaje świat podobny do… no cóż, taki jak Windows Vista lub Upstart w Linuksie to dobre przykłady wielu małych skrótów prowadzących do „wzdęcia i unosić się”, jak w martwych w wodzie. oboje też są brzydcy. dlaczego nie użyć str (). join (a), które jest w 100% wyraziste imfho ..
osirisgothra

4

Działa również funkcja redukcji

import operator
h=['a','b','c','d']
reduce(operator.add, h)
'abcd'

1
Zawsze denerwuje mnie to, że operatorzy nie są obywatelami pierwszej klasy. Na przykład w schemacie byłoby to (redukcja + h)
Brian Minton

W schemacie (reduce + '' h)lub (apply + h)działałoby. Ale z drugiej strony, w Pythonie operator dodania przyjmuje dokładnie 2 operandy, stąd potrzeba redukcji. W przeciwnym razie możesz to zrobić operator.add(*h), ponieważ applyzostał on oficjalnie uznany za przestarzały w Pythonie na rzecz rozszerzonej składni wywołania (alias en.wikipedia.org/wiki/Variadic_function )
Brian Minton

3

Jeśli lista zawiera liczby, możesz używać map()zjoin() .

Na przykład:

>>> arr = [3, 30, 34, 5, 9]
>>> ''.join(map(str, arr))
3303459

w rzeczywistości jest bardziej pytoniczny w użyciu''.join([str(i) for i in arr])
user1767754

@ user1767754 Cóż, Guido woli ten styl, ale nie ma absolutnie nic złego w korzystaniu z funkcji mapy.
itsbruce

2
h = ['a','b','c','d','e','f']
g = ''
for f in h:
    g = g + f

>>> g
'abcdef'

6
To byłoby dość powolne. Użycie ''.join(h)znacznie przewyższy metodę dodawania jeden po drugim.
Martijn Pieters

1
w „Biblii Pythona” (ta 1400+ strona pierwsza), w wielu miejscach mówi nam, że jest to niewłaściwe i należy tego unikać, gdy tylko jest to możliwe. Jest to również boleśnie oczywisty znak towarowy niedoinformowanego początkującego Pythona (aby nie obrażać funkcjonalności ... no cóż) może działać, ale usłyszysz „Nie rób tego” od około 5000 osób za robienie tego.
osirisgothra

2

poza tym, str.joinco jest najbardziej naturalnym sposobem, istnieje możliwość użycia io.StringIOi nadużywania writelinesdo pisania wszystkich elementów za jednym razem:

import io

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

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

drukuje:

abcd

Kiedy używasz tego podejścia z funkcją generatora lub iterowalną, która nie jest a tuplelub a list, zapisuje to tworzenie tymczasowej listyjoin która umożliwia przydzielenie odpowiedniego rozmiaru za jednym razem (a lista łańcuchów 1-znakowych jest bardzo droga pod względem pamięci ).

Jeśli masz mało pamięci i masz leniwie oceniany obiekt jako dane wejściowe, takie podejście jest najlepszym rozwiązaniem.


0

Możesz również użyć operator.concat()tego w następujący sposób:

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

Jeśli używasz Python 3, musisz przygotować:

>>> from functools import reduce

odkąd wbudowane reduce()zostało usunięte z Python 3 i teraz mieszka w functools.reduce().

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.