2015-10-10 13 views
15

Poco fa ho visto un quiz on this page:Confondere circa un Python min quiz

>>> x, y = ??? 
>>> min(x, y) == min(y, x) 
False 

L'esempio risposta è

x, y = {0}, {1} 

Dalla documentazione so che:

min(iterable[, key=func]) -> value
min(a, b, c, ...[, key=func]) -> value

With a single iterable argument, return its smallest item.
With two or more arguments, return the smallest argument.

Ma perché è min({0},{1})={0} e min({1},{0})={1}?

Ho anche provato pochi altri:

min({0,2},1) # 1 
min(1,{0,2}) # 1 
min({1},[2,3]) # [2,3] 
min([2,3],1) # 1 
+1

stampare le variabili, il {} è un insieme di [] è una lista .. ecc – C1sc0

+0

Quell'esempio risposta è sbagliata. (http://i.imgur.com/C9nYDTF.png) – Elipzer

+0

@ C1sc0 Lo so. ma perché il risultato? –

risposta

7

min è implementato meno così:

def min(*args): 
    least = args[0] 
    for arg in args: 
     if arg < least: 
      least = arg 
    return least 

Il modo in cui il lavoro operatori di confronto per gli insiemi di rompere una delle ipotesi che questo rende implicitamente: che per ogni coppia di oggetti, o sono uguali, o a < b o b < a. Né {0}{1} si confrontano l'uno con l'altro, quindi min fornisce risposte incoerenti.

Gli altri risultati visualizzati sono a causa delle regole su come Python definisce un ordine per tipi misti. A set e uno int non sono confrontabili: nessuno di questi tipi definisce una regola per il confronto con l'altro. Ciò porta Python 2 ad applicare una regola chiamata "ordine arbitrario ma coerente" - uno dei tipi è scelto per essere il tipo "inferiore", e rimarrà il tipo più basso per tutta la durata del programma. In pratica, sarà lo stesso su tutto il codice che si esegue, poiché viene implementato confrontando i nomi dei tipi in ordine alfabetico, ma in teoria potrebbe cambiare.

La regola "ordine arbitrario ma coerente" è stata scaricata da Python 3, perché l'unico effetto effettivo era quello di mascherare i bug. Quando non c'è regola definita per la ricerca di un ordine, Python ora si dice così:

>>> 1 < {0} 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
TypeError: unorderable types: int() < set() 
+0

Assorbo assolutamente la codifica, quindi mi scuso se sono sbagliato, ma penso che dovrebbe essere "se arg

+0

A proposito, e sono sicuro che questa potrebbe essere una lunga risposta quindi se non hai tempo apprezzerei davvero un riferimento a un altro post o articolo, ma perché stai passando il tuo argomento per riferimento, quali sono i vantaggi e svantaggi? –

+0

@jeremy sì, quello era davvero un errore. Per quanto riguarda il passaggio per riferimento, non è ciò che il '* significa - Python non fa puntatori come C (* all * l'argomento passing è più simile a un riferimento C++, eccetto che la riassegnazione del nome non influenza l'oggetto originale - i documenti lo chiamano [pass by incarico] (https://docs.python.org/3/faq/programming.html#how-do-i-write-a-function-with-output-parameters-call-by -reference). Il '*' è il modo in cui Python fa i varargs - significa che puoi chiamarlo come 'min (1,2,3)', ecc., come molti argomenti che vuoi, e li raccoglierà tutti in un lista chiamata 'args'. – lvc

9

Gli operatori di confronto <, <=, >= e > controllare se un insieme è un sottoinsieme rigoroso, sottoinsieme, sovrainsieme o rigorosa sovrainsieme di un altro, rispettivamente.

{0} e {1} sono False per tutti questi, quindi il risultato dipende dall'ordine di controllo e dall'operatore.

+0

per '1' e' {0,2} 'perché è sempre 1? –

8

Il punto chiave qui è che le due serie non sono sottoinsiemi di ogni altro, in modo entrambi sono False per < anche se non sono uguali:

>>> {0} < {1} 
False 
>>> {0} > {1} 
False 
>>> {0} == {1} 
False 

Così che uno è più piccolo? Il fatto che i set non forniscano strict weak ordering significa che non c'è una risposta corretta.

+0

puoi dire perché '1' <' {0,2} 'in python? –

+4

In Python 2.x, diversi tipi di oggetti sono confrontati con le loro stringhe di tipo, il che non ha molto senso per me. In Python 3.x, '1 <{0,2}' è illegale. –

+1

@YuHao Sì, si noti che '1 <{0,2}' genererà 'TypeError: types non ordinabili: int()

Problemi correlati