Bir karakter listesini bir dizeye dönüştürme


Yanıtlar:


585

Aradaki joinboş dizeyle birlikte tüm dizeleri birleştirmek için boş dizenin yöntemini kullanın, şöyle:

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

1
karakterler arasına nasıl boşluk ekleyebilirim? zaten her şeyi yinelemeden yapmak için?
clifgray

18
sadece ' '.join(list)tırnak işaretleri arasında bir boşluk yapın
clifgray

Bununla ilgili güzel bir şey, her öğe için yeni satırlarla bir
txt'ye

28
Açıklığa kavuşturmak için: "".join(['a','b','c'])anlamına gelir Join all elements of the array, separated by the string "". Aynı şekilde, " hi ".join(["jim", "bob", "joe"])yaratacaktır "jim hi bob hi joe".
Jack,

39

Bu JavaScript ve Ruby gibi birçok popüler dilde çalışıyor, neden Python'da değil?

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

Python'da joinyöntem strsınıfta yeterince garip :

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

Nesnede neden JavaScript veya diğer popüler kod dillerinde olduğu gibi joinbir yöntem yok list? Python topluluğunun nasıl düşündüğüne bir örnektir. Join bir dize döndürdüğünden, liste sınıfına değil, dize sınıfına yerleştirilmelidir, bu nedenle str.join(list)yöntem şu anlama gelir: listeyi strayırıcı olarak kullanarak yeni bir dizeye birleştirir (bu durumda strboş bir dizedir).

Her nasılsa bir süre sonra bu şekilde düşünmeyi sevmeliyim. Python tasarımında pek çok şeyden şikayet edebilirim, ancak tutarlılığı hakkında değil.


1
Bir liste yöntemi yerine bir dize yöntemi olmanın temel nedeni , yalnızca bir liste değil, yinelenebilir herhangi bir öğeyi kabul etmesidir . Jeneratör ifadelerini, sözlükleri, kümeleri, çeşitli görünümleri vb. Kullanabilirsiniz. Bu yüzden çoğu dilde dizi birleştirme işleminden çok daha esnektir.
rosuav

Python'ları birçok dinamik dilde string.join()bir join()yöntemi olan çoğu koleksiyonla karşılaştırıyordum . Tekrarlanabilirler hakkında, sanırım bu diller için bir sorun değil, çünkü yöntemde bir toplama yapıcısına ve zincire yinelenebilirliği dahil etmek kolay (ve okunaklı) join().
Paulo Scardine

Evet, ya tembel listelere sahip olduklarını (Haskell tarzı) varsayalım ya da başlamadan önce listeyi hafızaya birleştirmekten hoşlanıyorsunuz. Demek istediğim, Python'un yapma şeklinin keyfi olmaması, çok iyi bir gerekçesi var.
rosuav

1
Keyfi değil, her sınıfta isim alanı kirliliğini önlemek için bir tasarım kararı. :-)
Paulo Scardine

Kesinlikle. Ayrıca, bunların hepsi sınıf bile değildir - "yinelenebilir" bir sınıf değil, bir protokoldür. Herhangi bir yinelenebilir kullanarak filtre uygulayabilir, eşleyebilir, katılabilir, vb.
rosuav

15

Python yorumlayıcınız eskiyse (örneğin, bazı eski Linux dağıtımlarında yaygın olan 1.5.2), join()herhangi bir eski dize nesnesinde yöntem olarak kullanılamayabilir ve bunun yerine dize modülünü kullanmanız gerekir. Misal:

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

try:
    b = ''.join(a)

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

Dize bolacaktır 'abcd'.


10

Bu en hızlı yol olabilir:

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

4
@WinstonEwert evet, dün böyle bir şey yapması gereken bir program yazıyordum ve programımdaki bu satır sayılarının performansı için birkaç yol karşılaştırdım, sonuç o zaman yaklaşık% 20 daha hızlı olduğunu gösteriyor''.join(['a','b','c'])
bigeagle

2
Kendi karşılaştırmalı değerlendirmelerim 7 kat daha hızlı. pastebin.com/8nSc5Ek1 . Kıyasınızı paylaşmak ister misiniz?
Winston Ewert

1
@WinstonEwert Haklısın. Bunun nedenini buldum: benim programda ağdan int bir listesini recv sonra map(ord,a)gereksiz yere dizeye dönüştürmek , ama ihtiyaçlarını katılmak map(chr,a). İşte benim karşılaştırmalı değerlendirme pastebin.com/1sKFm8ma
bigeagle

15
Erken optimizasyon. Neler olup bittiğini anlamak ve anlamak çok zor. Kullanıcı işlem sırasında performansa İHTİYACI OLMADIĞI sürece, basit ''.join()bir çok daha okunabilir.
Luiz Damim

5
katılmıyorum - programcıların bu tür şeyler için en hızlı yöntemleri akıllarında tutmaları gerekir. biraz daha uzun süren basit bir işlem önemli değildir. Bununla birlikte, yazılan her programın şişmesi ve çok fazla kaynak alması bu şekilde gerçekleşir. Kendimizi işleri olabildiğince yalın yapma alışkanlığına sokmadığımızda, böyle bir dünya ile sonuçlanırız ... Windows Vista veya Linux'ta Upstart gibi birçok küçük kısayolun iyi örnekleridir. suda ölü gibi, 'şişir ve yüzer'. ikisi de çirkin. Neden% 100 etkileyici imfho olan str (). join (a) kullanmıyorsunuz ..
osirisgothra

4

Azaltma işlevi de çalışır

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

1
Operatörlerin kendi başlarına birinci sınıf vatandaş olmamaları beni her zaman rahatsız ediyor. Örneğin, şemada, bu olurdu (azaltma + s)
Brian Minton

Şemada, (reduce + '' h)ya (apply + h)da işe yarayacaktı. Ama sonra tekrar, Python'da, ekleme operatörü tam olarak 2 işlenen alır, dolayısıyla azaltma ihtiyacı. Aksi takdirde, yapabilirsin operator.add(*h), çünkü applyresmi olarak Python'da genişletilmiş çağrı sözdizimi lehine kullanımdan kaldırıldı (aka en.wikipedia.org/wiki/Variadic_function )
Brian Minton

3

Liste numaralarını varsa, kullanabilirsiniz map()ilejoin() .

Örneğin:

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

aslında daha ''.join([str(i) for i in arr])
pitonik

@ user1767754 Guido bu stili tercih ediyor, ancak harita işlevini kullanmanın kesinlikle yanlış bir yanı yok.
itsbruce

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

>>> g
'abcdef'

6
Bu oldukça yavaş olurdu. Kullanmak ''.join(h), tek tek ekleme yönteminizden çok daha uzak olacaktır.
Martijn Pieters

1
'the' python incili'nde (o 1400+ sayfa bir), birçok yerde bunun yanlış olduğunu ve mümkün olduğunda kaçınılması gerektiğini söyler. Ayrıca, bilgisiz python acemisinin (işlevselliğe hakaret etmemek için ... iyi değil) acı verici bir ticari markası olabilir, ancak bunu yapmak için yaklaşık 5000 kişiden "Bunu yapma" ifadesini duyacaksınız.
osirisgothra

2

str.joinen doğal yolun yanı sıra , tüm öğeleri tek seferde yazmak için kullanmak io.StringIOve kötüye kullanmak writelines:

import io

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

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

baskılar:

abcd

Bu yaklaşımı bir üreteç işleviyle veya a tupleveya a olmayan bir yinelemeyle kullanırken list, geçici liste oluşturmayı kaydeder.join doğru boyutu ayırmak için (ve 1 karakterli dizelerin listesi bellek açısından çok pahalıdır ).

Belleğiniz yetersizse ve giriş olarak tembel olarak değerlendirilen bir nesneniz varsa, bu yaklaşım en iyi çözümdür.


0

Ayrıca şöyle kullanabilirsiniz operator.concat():

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

Python 3'ü kullanmanız gerekiyorsa:

>>> from functools import reduce

yerleşik reduce()Python 3 kaldırıldı ve şimdi yaşıyor functools.reduce().

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.