In che modo Python 2 confronta string e int? Perché gli elenchi sono più grandi dei numeri e le tuple maggiori degli elenchi?


178

Il seguente frammento è annotato con l'output ( come visto su 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

Qualcuno può spiegare perché l'output è come tale?


Dettagli di implementazione

  • Questo comportamento è richiesto dalle specifiche della lingua o dipende dagli implementatori?
  • Ci sono differenze tra le principali implementazioni di Python?
  • Ci sono differenze tra le versioni del linguaggio Python?

23
Dei 3000 duplicati di questa domanda, questo ha una risposta che spiega perché il linguaggio è stato progettato in questo modo (e perché è stato riprogettato in 3.x). Questo non fa parte di questa domanda, ma fa parte di molte delle domande che vengono collegate qui.
abarnert,

Risposte:


209

Dal manuale di python 2 :

Dettagli dell'implementazione di CPython: gli oggetti di tipi diversi, tranne i numeri, sono ordinati in base al nome del tipo; oggetti dello stesso tipo che non supportano il confronto corretto sono ordinati in base al loro indirizzo.

Quando ordini due stringhe o due tipi numerici, l'ordinamento viene eseguito nel modo previsto (ordinamento lessicografico per stringa, ordinamento numerico per numeri interi).

Quando ordini un tipo numerico e non numerico, il tipo numerico viene prima.

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

Quando ordini due tipi incompatibili in cui nessuno dei due è numerico, vengono ordinati in base all'ordine alfabetico dei loro nomi:

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

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

Un'eccezione sono le lezioni di vecchio stile che vengono sempre prima delle lezioni di nuovo stile.

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

Questo comportamento è richiesto dalle specifiche della lingua o dipende dagli implementatori?

Non ci sono specifiche di lingua . Il riferimento linguistico dice:

Altrimenti, oggetti di diverso tipo si confrontano sempre in modo diseguale e sono ordinati in modo coerente ma arbitrario.

Quindi è un dettaglio di implementazione.

Ci sono differenze tra le principali implementazioni di Python?

Non posso rispondere a questo perché ho usato solo l'implementazione ufficiale di CPython, ma ci sono altre implementazioni di Python come PyPy.

Ci sono differenze tra le versioni del linguaggio Python?

In Python 3.x il comportamento è stato modificato in modo che il tentativo di ordinare un numero intero e una stringa genererà un errore:

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

55
Va bene che lo hanno cambiato in Py3k. Quando ho visto per la prima volta questa domanda, i miei pensieri erano "cosa, questo non genera un errore?".
JAL

9
NB Un'eccezione alla regola 2.x secondo cui tipi diversi sono ordinati in base al nome del tipo è che l'oggetto None viene sempre confrontato con un valore inferiore rispetto a qualsiasi altro tipo. Nel 3.x il confronto di None con un altro tipo genererà comunque un TypeError.
Dave Kirby,

4
@KarelBilek: bool è un tipo numerico. E True == 1, quindi non è né <né>.
abarnert,

3
Ordine lessografico dei nomi dei loro tipi? Quando vorresti mai che fosse una caratteristica? Chi lo userebbe mai?
Jack

3
complex(1,0) > 'abc'Falsecomplex(1,0) > complex(0,0)TypeError
Curiosità

24

Le stringhe vengono confrontate lessicograficamente e i tipi diversi vengono confrontati con il nome del loro tipo ( "int"< "string"). 3.x risolve il secondo punto rendendoli non comparabili.


3
Ma in python2 gli int sono meno di dicts quindi non può essere solo lessicograficamente per nome?
Tony Suffolk, 66

Ho appena trovato questa risposta e sono d'accordo con Tony Suffolk. Gli oggetti NON sono ordinati in base al nome del tipo quando diversi.
Exelian,

@ TonySuffolk66 tipo numerico fa eccezione a quella regola. NumericType è sempre inferiore a qualsiasi altro tipo (tranne NoneType) in 2.7.
lef
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.