Duvida comportamento cmp python

15 views
Skip to first unread message

Cassio

unread,
May 17, 2013, 12:40:30 PM5/17/13
to python...@googlegroups.com
Recentemente um grande nome do python o @raymondh publicou o seguinte tweet.

#python2 puzzle: Predict and explain the sort order of: sorted([u'tim', (10, 20, 30), 'guido', u'barry', None])

Não consegui entender o resultado desta ordenação.Alguém sabe explicar?

Robson Roberto Souza Peixoto

unread,
May 17, 2013, 1:19:32 PM5/17/13
to python...@googlegroups.com
Eu não entendo PN de python, mas não seria por causa do atributo __str__ ?


2013/5/17 Cassio <cassio...@gmail.com>
Recentemente um grande nome do python o @raymondh publicou o seguinte tweet.

#python2 puzzle: Predict and explain the sort order of: sorted([u'tim', (10, 20, 30), 'guido', u'barry', None])

Não consegui entender o resultado desta ordenação.Alguém sabe explicar?

--
--
------------------------------------
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ê está recebendo esta mensagem porque se inscreveu no grupo "python-brasil" dos Grupos do Google.
Para cancelar a inscrição neste grupo e parar de receber seus e-mails, envie um e-mail para python-brasi...@googlegroups.com.
Para obter mais opções, acesse https://groups.google.com/groups/opt_out.
 
 



--
Robson Roberto Souza Peixoto
Robinho http://robsonpeixoto.com/
Master in Computer Science, University of Campinas
Linux Counter #395633
IRC: robsonpeixoto
Twitter: http://twitter.com/rrspba
github: https://github.com/robsonpeixoto

Joao S. O. Bueno

unread,
May 19, 2013, 2:17:03 PM5/19/13
to Python Brasil
2013/5/17 Cassio <cassio...@gmail.com>:
Então ---
demorei um pouco, e consegui entender o que acontece -
(mas muito longe de tentar prever o que iria acontecer - se tivesse tentado,
eu teria errado).

Bom, primeiro, pra quem não fez - o resultado é esse:

>>> sorted([u'tim', (10, 20, 30), 'guido', u'barry', None])
[None, u'barry', 'guido', (10, 20, 30), u'tim']

----
E de todas as coisas estranahs ai, o que é realmente inusitado é o
u"tim" no final,
enquanto a tupla (10,20,30) fica no meio - achoque o resultado esperado ai seria
que os objetos de tipos iguais ficassem juntos, e os objetos string e
unicode ficassem juntos também, em ordem alfabética.

Bom... o resultado "mais correto" pra isso, na verdade é o do Python 3:
tentar ordenar essa lista dá um "TypeError" por que estão sendo comparados
objetos de tipos diferentes, que não tem comparação definida entre si.

Python 2 não dá "typeerror" - em vez disso, uma comparação entre
objetos de tipos diferentes de fato colcoa todos
os objetos de um mesmo tipo sempre antes, ou sempre depois de outro.

Repita a ordenação acima, mas com três strings nicode, ou três byte-strings,
em vez de misturar os dois tipos, e dá pra começar a entender o que acontece:

>>> sorted([u'tim', (10, 20, 30), u'guido', u'barry', None])
[None, (10, 20, 30), u'barry', u'guido', u'tim']

>>> sorted(['tim', (10, 20, 30), 'guido', 'barry', None])
[None, 'barry', 'guido', 'tim', (10, 20, 30)]

Então, por que a Tupla fica no meio, no exemplo original?
è por que a comparação entre (byte) strings e unicode strings é
definida em Python 2 (com uma conversão implícita pra Unicode, fonte
de muitos "UnicodeDecode Errors") - Só que strings e tuplas so tipos
diferentes, e
não há uma comparação distinta para as mesmas. Então se cai na história de
"objetos de um tipo A sao sempre maiores (ou menores) que objetodo tipo "B" )
Entãp a comparação de qualquer
string com uma tupla sempre fala que a (byte) string vem antes da tupla - -

>>> "" < ()
True

e a (unicode) string sempre vem depois da tupla.
>>> u"" < ()
False

Quando o algoritmo de ordenação faz as comparações nos elementos
da essa lista patológica, os resultados são inconsistentes:
u"tim" é maior que a tupla, e u"barry" também - mas u"barry" é menor que
"guido", que é menor que a tupla - daí a confusão toda.

Bom, passada a curiosidade, fica a moral da história:

1) Não misture strigns Unicode com (byte) strings
2) se estiver tratando de texto, ponha sua string como unicode
3) Se ainda não souber direito a diferença, pare tudo o mais que estiver fazendo
e leia agora:
http://va.mu/cXGl
(é, o famoso artigo do Joel on Software pra quem já conhece)
>
Reply all
Reply to author
Forward
0 new messages