Respostas:
Use o join
método da cadeia vazia para unir todas as cadeias com a cadeia vazia no meio, da seguinte maneira:
>>> a = ['a', 'b', 'c', 'd']
>>> ''.join(a)
'abcd'
' '.join(list)
com um espaço entre as aspas
"".join(['a','b','c'])
significa Join all elements of the array, separated by the string ""
. Da mesma maneira, " hi ".join(["jim", "bob", "joe"])
criará "jim hi bob hi joe"
.
Isso funciona em muitas linguagens populares como JavaScript e Ruby, por que não no Python?
>>> ['a', 'b', 'c'].join('')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'list' object has no attribute 'join'
Estranho o suficiente, em Python, o join
método está na str
classe:
# this is the Python way
"".join(['a','b','c','d'])
Por que join
não há um método no list
objeto como no JavaScript ou em outras linguagens de script populares? É um exemplo de como a comunidade Python pensa. Como join está retornando uma string, ela deve ser colocada na classe string, não na classe list, portanto o str.join(list)
método significa: ingressar na lista em uma nova string usando str
como separador (neste caso, str
uma string vazia).
De alguma forma, eu adorei esse modo de pensar depois de um tempo. Eu posso reclamar de muitas coisas no design do Python, mas não de sua coerência.
string.join()
com a maioria das coleções com um join()
método em muitas linguagens dinâmicas. Sobre iterables, acho que não é um problema para essas linguagens porque é tão fácil (e legível) incluir o iterável em um construtor de coleção e cadeia no join()
método.
Se o seu intérprete Python for antigo (1.5.2, por exemplo, o que é comum em algumas distribuições Linux mais antigas), talvez você não esteja join()
disponível como método em nenhum objeto string antigo e precisará usar o módulo string. Exemplo:
a = ['a', 'b', 'c', 'd']
try:
b = ''.join(a)
except AttributeError:
import string
b = string.join(a, '')
A string b
será 'abcd'
.
Esta pode ser a maneira mais rápida:
>> from array import array
>> a = ['a','b','c','d']
>> array('B', map(ord,a)).tostring()
'abcd'
''.join(['a','b','c'])
map(ord,a)
é desnecessário, mas junte as necessidades map(chr,a)
. Aqui está o meu benchmark pastebin.com/1sKFm8ma
''.join()
é muito mais legível.
A função de redução também funciona
import operator
h=['a','b','c','d']
reduce(operator.add, h)
'abcd'
(reduce + '' h)
ou (apply + h)
iria funcionar. Mas, novamente, em Python, o operador add leva exatamente 2 operandos, daí a necessidade de redução. Caso contrário, você poderia fazer operator.add(*h)
, uma vez que apply
foi oficialmente removida em Python em favor da sintaxe de chamada estendida (aka en.wikipedia.org/wiki/Variadic_function )
Se a lista contiver números, você pode usar map()
com join()
.
Por exemplo:
>>> arr = [3, 30, 34, 5, 9]
>>> ''.join(map(str, arr))
3303459
''.join([str(i) for i in arr])
h = ['a','b','c','d','e','f']
g = ''
for f in h:
g = g + f
>>> g
'abcdef'
''.join(h)
superaria em muito o método de acréscimo um por um.
além de str.join
qual é o caminho mais natural, uma possibilidade é usar io.StringIO
e abusar writelines
para escrever todos os elementos de uma só vez:
import io
a = ['a','b','c','d']
out = io.StringIO()
out.writelines(a)
print(out.getvalue())
impressões:
abcd
Ao usar essa abordagem com uma função geradora ou uma iterável que não seja a tuple
ou a list
, ela salva a criação temporária de listas que join
faz para alocar o tamanho certo de uma só vez (e uma lista de cadeias de caracteres de 1 caractere é muito cara em termos de memória )
Se você tem pouca memória e tem um objeto avaliado preguiçosamente como entrada, essa abordagem é a melhor solução.
Você também pode usar operator.concat()
assim:
>>> from operator import concat
>>> a = ['a', 'b', 'c', 'd']
>>> reduce(concat, a)
'abcd'
Se você estiver usando o Python 3, precisará acrescentar:
>>> from functools import reduce
desde que o builtin reduce()
foi removido do Python 3 e agora vive functools.reduce()
.