Converter uma lista de caracteres em uma sequência


Respostas:


585

Use o joinmé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'

1
como posso adicionar espaços entre os caracteres? de qualquer maneira fazê-lo sem percorrer a coisa toda?
Clifgray

18
apenas fazer ' '.join(list)com um espaço entre as aspas
clifgray

Uma coisa boa sobre isso é que você pode usar '\ n'.join (a) se quiser escrever uma lista em um txt com novas linhas para cada item
Norfeldt

28
Esclarecer: "".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".
Jack

39

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 joinmétodo está na strclasse:

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

Por que joinnão há um método no listobjeto 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 strcomo separador (neste caso, struma 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.


1
O principal motivo para a associação ser um método de string em vez de um método de lista é que ele aceita qualquer iterável , não apenas uma lista. Você pode usar expressões geradoras, dicionários, conjuntos, visualizações de vários tipos e assim por diante. Portanto, é muito mais flexível que a operação de junção da matriz na maioria dos idiomas.
rosuav

Eu estava comparando o Python 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.
Paulo Scardine 17/08/16

Sim, supondo que eles tenham listas preguiçosas (estilo Haskell) ou você se sinta à vontade para juntar a lista na memória antes de começar. Meu argumento é que o modo de fazer do Python não é arbitrário, tem uma justificativa muito boa.
rosuav

1
Não é arbitrário, é uma decisão de projeto evitar a poluição do namespace em todas as classes. :-)
Paulo Scardine 17/08/16

Exatamente. Além disso, nem todas são classes - "iterável" é um protocolo, não uma classe. Você pode filtrar, mapear, participar, etc, usando qualquer iterável.
rosuav

15

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 bserá 'abcd'.


10

Esta pode ser a maneira mais rápida:

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

4
@WinstonEwert sim, ontem eu estava escrevendo um programa que precisa de fazer tal coisa, e eu aferido algumas maneiras para o desempenho desta linha contagens em meu programa, os shows resultado é cerca de 20% mais rápido, então''.join(['a','b','c'])
bigeagle

2
Meus próprios programas de benchmark são 7 vezes mais rápidos. pastebin.com/8nSc5Ek1 . Você se importa de compartilhar sua referência?
Winston Ewert

1
@WinstonEwert Você está certo. Eu encontrei a razão para isso: no meu programa, recv uma lista de int da rede e depois converto para string onde map(ord,a)é desnecessário, mas junte as necessidades map(chr,a). Aqui está o meu benchmark pastebin.com/1sKFm8ma
bigeagle

15
Otimização prematura. É muito difícil ler e entender o que está acontecendo. A menos que o usuário precise de desempenho na operação, um simples ''.join()é muito mais legível.
Luiz Damim 26/10/12

5
discordo - os programadores precisam ter em mente os métodos mais rápidos para essas coisas. uma única operação simples que demora um pouco mais não é grande coisa. No entanto, é assim que praticamente todos os programas escritos acabam inchando e consumindo muitos recursos. Quando não nos habituamos a deixar as coisas o mais enxutas possível, acabamos com um mundo que é ... bem, como o Windows Vista ou o Upstart no Linux, são bons exemplos de muitos pequenos atalhos que levam a 'inchar e flutuar', como morto na água. ambos são feios também. por que não usar str () juntar-se (a) que é 100% expressiva imfho ...
osirisgothra

4

A função de redução também funciona

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

1
Sempre me incomoda que os operadores não sejam cidadãos de primeira classe. No esquema, por exemplo, que seria (reduzir + H)
Brian Minton

No esquema, (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 applyfoi oficialmente removida em Python em favor da sintaxe de chamada estendida (aka en.wikipedia.org/wiki/Variadic_function )
Brian Minton

3

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

na verdade, é mais pythonic para usar #''.join([str(i) for i in arr])
user1767754

@ user1767754 Bem, Guido prefere esse estilo, mas não há absolutamente nada de errado em usar a função de mapa.
itsbruce

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

>>> g
'abcdef'

6
Isso seria bem lento. Usar ''.join(h)superaria em muito o método de acréscimo um por um.
Martijn Pieters

1
na Bíblia python '(aquela 1400+ página um), em muitos lugares, nos diz que isso é errado de fazer e deve ser evitado sempre que possível. Também é uma marca registrada dolorosamente óbvia do iniciante em python desinformado (para não insultar a funcionalidade ... bem) pode funcionar, mas você ouvirá "Não faça isso" de cerca de 5000 pessoas por fazê-lo.
Osirisgothra

2

além de str.joinqual é o caminho mais natural, uma possibilidade é usar io.StringIOe abusar writelinespara 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 tupleou a list, ela salva a criação temporária de listas que joinfaz 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.


0

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().

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.