web-dev-qa-db-fra.com

Comment Python 2 compare-t-il string et int? Pourquoi les listes se comparent-elles plus que des nombres et les tuples plus grands que des listes?

L'extrait suivant est annoté avec la sortie ( comme on peut le voir sur ideone.com ):

print "100" < "2"      # True
print "5" > "9"        # False

print "100" < 2        # False
print 100 < "2"        # True

print 5 > "9"          # False
print "5" > 9          # True

print [] > float('inf') # True
print () > []          # True

Quelqu'un peut-il expliquer pourquoi la sortie est en tant que telle?


Détails d'implémentation

  • Ce comportement est-il imposé par la spécification de langage, ou est-ce la responsabilité des implémenteurs?
  • Existe-t-il des différences entre les principales implémentations Python?
  • Existe-t-il des différences entre les versions du langage Python?
171
polygenelubricants

De la manuel de Python 2 :

Détail de l'implémentation CPython: les objets de types différents, à l'exception des nombres, sont classés en fonction de leurs noms de types; Les objets du même type qui ne permettent pas une comparaison correcte sont classés en fonction de leur adresse.

Lorsque vous commandez deux chaînes ou deux types numériques, l'ordre est effectué de la manière attendue (ordre lexicographique pour une chaîne, ordre numérique pour les entiers).

Lorsque vous commandez un type numérique et un type non numérique, le type numérique vient en premier.

>>> 5 < 'foo'
True
>>> 5 < (1, 2)
True
>>> 5 < {}
True
>>> 5 < [1, 2]
True

Lorsque vous commandez deux types incompatibles où aucun des deux n'est numérique, ils sont classés par ordre alphabétique de leurs noms:

>>> [1, 2] > 'foo'   # 'list' < 'str' 
False
>>> (1, 2) > 'foo'   # 'Tuple' > 'str'
True

>>> class Foo(object): pass
>>> class Bar(object): pass
>>> Bar() < Foo()
True

Les classes de style ancien, qui précèdent toujours les classes de nouveau style, constituent une exception.

>>> class Foo: pass           # old-style
>>> class Bar(object): pass   # new-style
>>> Bar() < Foo()
False

Ce comportement est-il imposé par la spécification de langage, ou est-ce la responsabilité des implémenteurs?

Il y a pas de spécification de langue . Le référence du langage dit:

Sinon, les objets de types différents se comparent toujours de manière inégale et sont ordonnés de manière cohérente mais arbitraire.

C'est donc un détail de mise en œuvre.

Existe-t-il des différences entre les principales implémentations Python?

Je ne peux pas répondre à cette question car je n’ai utilisé que l’implémentation officielle de CPython, mais il existe d’autres implémentations de Python telles que PyPy.

Existe-t-il des différences entre les versions du langage Python?

Dans Python 3.x, le comportement a été modifié de sorte que la tentative de commande d'un entier et d'une chaîne génère une erreur:

>>> '10' > 5
Traceback (most recent call last):
  File "<pyshell#0>", line 1, in <module>
    '10' > 5
TypeError: unorderable types: str() > int()
204
Mark Byers

Les chaînes sont comparées lexicographiquement, et les types dissemblables sont comparés par le nom de leur type ("int" <"string"). 3.x corrige le deuxième point en les rendant non comparables.

23