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