A string Python é impressa como [u'String ']

142

Certamente será fácil, mas está realmente me incomodando.

Eu tenho um script que lê em uma página da web e usa Beautiful Soup para analisá-lo. Da sopa , extraio todos os links, pois meu objetivo final é imprimir o link.contents.

Todo o texto que estou analisando é ASCII. Eu sei que o Python trata as strings como unicode, e tenho certeza de que isso é muito útil, mas que não serve para nada no meu script pequenino.

Toda vez que imprimo uma variável que contém 'String', sou [u'String']impressa na tela. Existe uma maneira simples de colocar isso de volta em apenas ASCII ou devo escrever um regex para removê-lo?

gnuchu
fonte
possível duplicação da pergunta (e resposta) muito mais clara: stackoverflow.com/q/2464959/1390788
Terrabits
Isso responde sua pergunta? Qual é o prefixo u em uma string Python?
Terrabits

Respostas:

118

[u'ABC']seria uma lista de um elemento de cadeias unicode. Beautiful Soup sempre produz Unicode . Portanto, você precisa converter a lista em uma única cadeia unicode e, em seguida, convertê-la em ASCII.

Não sei exatamente como você conseguiu as listas de um elemento; o membro do conteúdo seria uma lista de strings e tags, o que aparentemente não é o que você possui. Supondo que você realmente sempre obtenha uma lista com um único elemento e que seu teste seja realmente apenas ASCII, você usaria isso:

 soup[0].encode("ascii")

No entanto, verifique se seus dados são realmente ASCII. Isso é bem raro. Muito mais provavelmente é latin-1 ou utf-8.

 soup[0].encode("latin-1")


 soup[0].encode("utf-8")

Ou você pergunta à Beautiful Soup qual era a codificação original e a recupera de novo nesta codificação:

 soup[0].encode(soup.originalEncoding)
oefe
fonte
6
Na verdade, você não precisa fazer a codificação, porque o OP está vendo apenas a cadeia repr porque é assim que você vê alguma coisa quando imprime uma lista. sopa [0] será suficiente para mostrar a str em vez de repr, mostrando o conteúdo da string e não o modificador de citação e unicode.
ironfroggy
2
Você não deve codificar o texto representado como Unicode para bytes na maioria dos casos: você deve imprimir Unicode diretamente em Python:print(', '.join([u'ABC' , u'...']))
jfs
26

Você provavelmente tem uma lista contendo uma string unicode. O reprdisso é [u'String'].

Você pode converter isso em uma lista de cadeias de bytes usando qualquer variação do seguinte:

# Functional style.
print map(lambda x: x.encode('ascii'), my_list)

# List comprehension.
print [x.encode('ascii') for x in my_list]

# Interesting if my_list may be a tuple or a string.
print type(my_list)(x.encode('ascii') for x in my_list)

# What do I care about the brackets anyway?
print ', '.join(repr(x.encode('ascii')) for x in my_list)

# That's actually not a good way of doing it.
print ' '.join(repr(x).lstrip('u')[1:-1] for x in my_list)
ddaa
fonte
1
Por favor, evite horrores como repr(x).lstrip('u')[1:-1]. Use algo como: em print ", ".join(my_list)vez disso, para formatar uma lista de strings Unicode.
JFS
1
O comentário diz: "Na verdade, essa não é uma boa maneira de fazê-lo". É só aqui para o lolz!
Ddaa
9
import json, ast
r = {u'name': u'A', u'primary_key': 1}
ast.literal_eval(json.dumps(r)) 

irá imprimir

{'name': 'A', 'primary_key': 1}
osmjit
fonte
1
esse método me parece muito gentil, por que não há votos? algum impacto no desempenho com o qual devemos nos preocupar?
jrich523
8

Se acessar / imprimir listas de elementos únicos (por exemplo, sequencialmente ou filtradas):

my_list = [u'String'] # sample element
my_list = [str(my_list[0])]
gevang
fonte
1
você faz uma compreensão da lista:my_list = [str(my_list[x]) for x in range(len(my_list))]
gevang
4

passe a saída para a função str () e removerá a conversão da saída unicode. também, imprimindo a saída, ela removerá as tags u ''.

waweru
fonte
4

[u'String'] é uma representação de texto de uma lista que contém uma string Unicode no Python 2.

Se você executar print(some_list), é equivalente a
print'[%s]' % ', '.join(map(repr, some_list)), por exemplo, criar uma representação de texto de um objeto Python com o tipo list,repr() função será chamada para cada item.

Não confunda um objeto Python e sua representação de texto - repr('a') != 'a'e mesmo a representação de texto da representação de texto é diferente:repr(repr('a')) != repr('a') .

repr(obj)retorna uma sequência que contém uma representação imprimível de um objeto. Seu objetivo é ser uma representação inequívoca de um objeto que possa ser útil para depuração, em um REPL. Frequentementeeval(repr(obj)) == obj .

Para evitar chamadas repr(), você pode imprimir os itens da lista diretamente (se forem todos strings Unicode), por exemplo:print ",".join(some_list) —exibe uma lista separada por vírgulas das strings:String

Não codifique uma cadeia de caracteres Unicode em bytes usando uma codificação de caracteres codificada, imprima diretamente o Unicode . Caso contrário, o código poderá falhar porque a codificação não pode representar todos os caracteres, por exemplo, se você tentar usar a 'ascii'codificação com caracteres não-ascii. Ou o código produz silenciosamente mojibake (dados corrompidos são transmitidos ainda mais em um pipeline) se o ambiente usar uma codificação incompatível com a codificação codificada.

jfs
fonte
3

Use diroutype na 'string' para descobrir o que é. Eu suspeito que seja um dos objetos de tag da BeautifulSoup, que imprime como uma string, mas realmente não é um. Caso contrário, ele estará dentro de uma lista e você precisará converter cada sequência separadamente.

De qualquer forma, por que você está se opondo ao uso do Unicode? Algum motivo específico?

sykora
fonte
Eu estive olhando o BeautifulSoup desde os últimos dias. Eu não conseguia descobrir como o gnuchu conseguiria você ['string'] e não [u'String ']. Seu comentário a Andrew Jaffe parece provar que é uma lista.
batbrat
3

Você realmente quer dizer u'String'?

De qualquer forma, você não pode fazer apenas str(string)uma string em vez de uma string unicode? (Isso deve ser diferente para o Python 3, para o qual todas as strings são unicode.)

Andrew Jaffe
fonte
Eu deveria ter sido mais claro. Estou usando str (), mas ainda estou obtendo saída como abaixo quando imprimo. [u'ABC '] [u'DEF'] [u'GHI '] [u'JKL'] Os dados são retirados como texto de uma página da Web, inseridos em um banco de dados (Google Appstore), depois recuperados e impressos.
gnuchu
-1

encode("latin-1") me ajudou no meu caso:

facultyname[0].encode("latin-1")
user1519904
fonte
-1

Talvez eu não entenda, por que você não pode simplesmente pegar o elemento.text e convertê-lo antes de usá-lo? por exemplo (não sei por que você faria isso, mas ...) encontre todos os elementos de rótulo da página da web e itere entre eles até encontrar um chamado MyText

        avail = []
        avail = driver.find_elements_by_class_name("label");
        for i in avail:
                if  i.text == "MyText":

Converta a string de i e faça o que você quiser fazer ... talvez esteja faltando alguma coisa na mensagem original? ou era isso que você estava procurando?

Steven
fonte
Você está perdendo a parte em que a pergunta é sobre como fazer "Converter a string de i".
Nathan Tuggy
ahhh, graças de todos os comentários eu pensei que o problema estava recebendo o valor a ser convertido
Steven
mas, para ser justo, o i.text é o valor real da string, não há necessidade de "retirá-lo de uma matriz", como algumas pessoas sugeriram se o rótulo elemet, por exemplo, tiver um valor de texto de [u'String '] i.text será String
Steven