UTF-8 dentro de listas no Python 2.7

398 views
Skip to first unread message

Luciano Zaneti

unread,
May 8, 2014, 1:47:31 PM5/8/14
to python...@googlegroups.com

Pessoal,

Estou tendo que usar o python 2.7 por causa do Arcgis 10.1 que não suporta python 3.
Ao trabalhar com listas no python 2.7 não estou conseguindo acertar a codificação dentro delas. Vejam o exemplo a seguir:
# -*- coding: utf-8 -*-
list = []
list.append("abacate")
list.append("mamão")
list.append("maçã")
for x in list:
    print(x)

Quanto imprimo cada elemento da lista o resultado sai normal:
abacate
mamão
maçã

No entanto, se imprimo a list em sí:
# -*- coding: utf-8 -*-
list = []
list.append("abacate")
list.append("mamão")
list.append("maçã")
print(list)

Os caracteres acentuados e cedilha ficam com erro de codificação dentro da lista:
['abacate', 'mam\xc3\xa3o', 'ma\xc3\xa7\xc3\xa3']

Já pesquisei de tudo e não encontrei ninguém com o mesmo problema, acho que deve ser algum detalhe simples que estou errando.
Alguém poderia me ajudar?

Alex

unread,
May 8, 2014, 4:09:59 PM5/8/14
to python...@googlegroups.com
Não sei a explicação teórica completa, mais sei que isso não é um problema.

Ao fazer print(list), você pede para o Python representar a lista como uma string na saída de dados.
Como consequência o resultado é o que você está vendo.

O Python, pelo menos na versão 2.7, não trata a representação de strings dentro de uma lista.

Uma forma de resolver seu problema seria criar uma nova forma de representar os dados.

print '[' + ', '.join([str(item) for item in l]) + ']'

Ademir Francisco da Silva

unread,
May 8, 2014, 4:18:29 PM5/8/14
to python...@googlegroups.com
Não testei mas acho que isto resolve ...

from __future__ import unicode_literals

Tem que ser o primeiro dos imports

1[],


Ademir
--
--
------------------------------------
Grupo Python-Brasil
http://www.python.org.br/wiki/AntesDePerguntar
 
<*> Para visitar o site do grupo na web, acesse:
http://groups.google.com/group/python-brasil
 
<*> Para sair deste grupo, envie um e-mail para:
python-brasi...@googlegroups.com

---
Você recebeu essa mensagem porque está inscrito no grupo quot;Python Brasil" dos Grupos do Google.
Para cancelar inscrição nesse grupo e parar de receber e-mails dele, envie um e-mail para python-brasi...@googlegroups.com.
Para mais opções, acesse https://groups.google.com/d/optout.


-- 
Ademir Francisco da Silva
Skype  ...: Ademir_Francisco_da_Silva

Fábio Cerqueira

unread,
May 8, 2014, 4:28:32 PM5/8/14
to python...@googlegroups.com
Luciano, 
o que é mostrado quando se faz print sua_lista é a representação do objeto que possa ser impressa na tela. No caso a representação de strings é essa mesmo. Não há nenhum erro neste caso.  

>>> print repr("mamão")

'mam\xc3\xa3o'

Como o Alex mostrou, você pode usar o método de string join.

Fábio Cerqueira

Renzo Nuccitelli

unread,
May 8, 2014, 4:40:01 PM5/8/14
to python-brasil
Eu uso sempre essa abordagem.

O encoding utf-8 acima do arquivo só serve para o python saber a codificação que o arquivo está escrito.

 Tentei achar um post do Ramalho onde ele explica de maneira detalhada toda a problemática de enconding e Python. Alguém tem esse post favoritado?

--
  Renzo Nuccitelli

Gleison Rodrigues

unread,
May 8, 2014, 5:51:36 PM5/8/14
to python...@googlegroups.com
Kra tem um pep que fala sobre isso. http://legacy.python.org/dev/peps/pep-3140/

So fazendo uma simplificacao do codigo do Alex.

O join numa lista ja pega o __str__
Então se tu quer que apareça "["  "]" tem que ser explicito

# -*- coding: utf-8 -*-
lista = []
lista.append("abacate")
lista.append("mamão")
lista.append("maçã")

print "[%s]" % (", ".join(lista))

Gleison Rodrigues

unread,
May 8, 2014, 6:32:05 PM5/8/14
to python...@googlegroups.com
Outra coisa não use a palavra "list" ela é palavra reservada.

>>> list("1234")
['1', '2', '3', '4']



--
Gleison Rodrigues

Luciano Zaneti

unread,
May 8, 2014, 7:51:48 PM5/8/14
to python...@googlegroups.com

Obrigado demais a toda a galera do post,

 Eu estava me batendo demais com isso. A questão é que eu estava tentando conectar uma PythonAddin do tipo Combobox do ArcGis 10.1 em uma lista de dados que estou extraindo de um banco Postgresql, através de um script em python 2.7. Daí eu conectei com o banco de dados, fiz a consulta e puchei a lista, daí na hora de puxar a lista na combobox os itens acentuados estavam vindo com erro de codificação. Eu estava achando que era uma questão de configuração do python 2.7. Com a explicação de vocês eu mexi no código conseguí resolver, agradeço imensamente a todos vocês, e segue o codigo final caso seja útil para alguém:

Foi fundamental a inclusão da linha 14 para a solução, não sei exatamente porque mais parece que quando os dados estavam saindo do objeto "cursor" provindo do banco de dados eles estavam perdendo o codificação correta, quando criei outra lista chamada "ListaFazendas" e recodifiquei para UTF-8 cada ítem de "cursor" tudo ficou certinho.

1  # coding: UTF-8
2
3  try:
4      db = psycopg2.connect(host='srvfsa18', user='postgres', password='domeliseu',dbname='postgres')
5  except:
6      pythonaddins.MessageBox("Falha na conexão com o banco de dados", 'INFO', 0)
7      quit()
8
9  cursor = db.cursor()
10 cursor.execute("SELECT fazenda FROM fazendas;")
11 ListaFazendas = []
12 for x in cursor:
13     ListaCadaFazenda = list(x)
14     y = str(ListaCadaFazenda[0]).decode('UTF-8')
15     ListaFazendas.append(y)
16 self.items = ListaFazendas

Message has been deleted

Alex

unread,
May 8, 2014, 8:16:15 PM5/8/14
to python...@googlegroups.com
''.join([1,2,3])
Traceback (most recent call last):
  File "<input>", line 1, in <module>
TypeError: sequence item 0: expected string, int found

O join numa lista ja pega o __str__

Sua declaração não é 100% válida. 
Se qualquer usuário novo considerar isso como verdade, 
teremos mais um tópico: "por que ''.join não trabalha como números".

Alex

unread,
May 8, 2014, 9:50:29 PM5/8/14
to python...@googlegroups.com
# coding=utf-8
from __future__ import unicode_literals  # Primeira tentativa, não funciona!

list_repr file

list_fruits = ["abacate", "mamão", "maçã"]

print(list_fruits)

# Segunda tentativa usando 'formatação manual' * funciona mas dá muito trabalho ! *

print("[{!s}]".format(', '.join([u'%s' % i for i in list_fruits])))


# Terceira tentativa (orientação a objetos).

class List(list):

    def __str__(self):
        string = []
        for s in self:
            if not isinstance(s, basestring):
                s = str(s)
            string.append(s if isinstance(s, unicode) else unicode(s, 'utf-8'))
        string = u"[{!s}]".format(u', '.join(string))  # only unicode string
        return string.encode('utf-8')  # bytes strings


list_fruits = List(("maçã", "abacate", "mamão"))
print('r: ', repr(list_fruits))

# Afetando o sistema embutido!

import __builtin__
__builtin__.list = List

list_fruits = list(("abacate", "mamão", "maçã"))
print(list_fruits)


# test_builtins file

# coding=utf-8
# import list_repr
#
# list_fruits = list(("abacate", "mamão", "maçã", 100, 200, list))
# print('r: ', repr(list_fruits))
#
# print('builtins changed')
# print(list_fruits)
Exemplos da saída de dados:

[u'abacate', u'mam\xe3o', u'ma\xe7\xe3']
[abacate, mamão, maçã]
(u'r: ', "[u'ma\\xe7\\xe3', u'abacate', u'mam\\xe3o']")
[abacate, mamão, maçã]
('r: ', "['abacate', 'mam\\xc3\\xa3o', 'ma\\xc3\\xa7\\xc3\\xa3', 100, 200, <class 'list_repr.List'>]")
builtins changed
[abacate, mamão, maçã, 100, 200, <class 'list_repr.List'>]


Espero que as considerações acima sejam úteis.



Em quinta-feira, 8 de maio de 2014 14h47min31s UTC-3, Luciano Zaneti escreveu:

Gleison Rodrigues

unread,
May 9, 2014, 9:36:51 PM5/9/14
to python...@googlegroups.com
Só uma observação Alex. O join é exclusivo para o uso em strings, o fato dele poder trabalhar com vetores não exclui que ele vai continuar trabalhando com strings.

Quando a impressão de uma lista de números, não a necessidade de converter pois a representação para o interpretador e a representação humana dos algarismos 0..9 são as mesmas.

então fica assim  

>>>print [1,2,3]
[1, 2, 3]

Quanto a afirmação que fiz do join ela esta 100% falsa.
Ele não faz uso direto do __str__ visitei a documentação e vi como funcionava corretamente 
Obrigado pelo alerta!


--
Gleison Rodrigues


--

Luciano Zaneti

unread,
May 13, 2014, 9:43:26 AM5/13/14
to python...@googlegroups.com

Pessoal,

Como vocês estavam explicando em python 2.7 os conteúdos das listas são armazenados em ASCII, que não tem suporte para caracteres acentuados, cedilha, etc.
Neste sentido me surgiu outra questão: Como ordenas as palavras dentro das listas?

Tenho a seguinte lista:
Lista = [“Califórnia”, “Paraíso”, “Água Nascente”, “Água Lima”, “Arizona”]

Ao ordenar - Lista.sort() – o resultado fica:
Lista = [“Arizona”, “Califórnia”, “Paraíso”, “Água Lima”, “Água Nascente”]

Quando o correto seria:
Lista = [“Água Lima”, “Água Nascente”, “Arizona”, “Califórnia”, “Paraíso”]

Existe alguma maneira de resolver este problema?

Alex

unread,
May 14, 2014, 2:52:00 PM5/14/14
to python...@googlegroups.com
http://www.python.org.br/wiki/TudoSobrePythoneUnicode

Após a leitura de 'TudoSobrePythoneUnicode', fica bem fácil entender porque 'list.sort' falha em ordenar o objeto.

Logo você terá que criar um função de comparação, e usá-la em conjunto com 'sorted'


Reply all
Reply to author
Forward
0 new messages