2015-10-10 14 views
15

Przed chwilą widziałem quiz na this page:Mylenie o Pythonie min quizu

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

Przykładowa odpowiedź jest

x, y = {0}, {1} 

Z dokumentacji wiem, że:

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.

Ale dlaczego jest min({0},{1})={0} i min({1},{0})={1}?

Próbowałem też kilka innych:

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

wydrukować zmiennych, {} jest zbiorem przycisk [] jest lista .. itp – C1sc0

+0

To przykład odpowiedź jest błędna. (http://i.imgur.com/C9nYDTF.png) – Elipzer

+0

@ C1sc0 Wiem. ale dlaczego wynik? –

Odpowiedz

7

min realizowany jest z grubsza tak:

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

Sposób pracy operatorów porównania dla zestawów złamać jeden z założenia, że ​​w sposób dorozumiany sprawia: że dla każdej pary przedmiotów, albo są one równe lub a < b lub b < a. Ani mniej, ani mniej niż jeden, dlatego {0} daje niespójne odpowiedzi.

Inne wyniki, które widzisz, wynikają z reguł określających sposób, w jaki Python definiuje zamówienie dla typów mieszanych. A set i int nie są porównywalne - żaden z tych typów nie definiuje reguły dla porównania z drugą. To powoduje, że Python 2 stosuje regułę zwaną "arbitralną, ale spójną kolejnością" - jeden z typów jest wybrany jako "niższy" i pozostanie dolnym typem przez cały okres istnienia programu. W praktyce będzie on taki sam dla wszystkich uruchamianych przez ciebie kodów, ponieważ jest implementowany przez porównywanie nazw typów alfabetycznie - ale teoretycznie może się to zmienić.

Reguła "arbitralna, ale spójna kolejność" została odrzucona z Python 3, ponieważ jedynym efektem, jaki naprawdę miał na celu zamaskowanie błędów. Gdy nie ma zdefiniowane reguły za znalezienie zlecenia, Python teraz powie tak:

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

Całkowicie ssam kodowanie, więc przepraszam jeśli jestem źle, ale myślę, że powinno być "jeśli arg

+0

Przy okazji, i jestem pewien, że to może być długa odpowiedź, więc jeśli nie masz czasu, naprawdę doceniam odwołanie do innego postu lub artykułu, ale dlaczego przekazujesz swój argument przez odniesienie, jakie są zalety wady? –

+0

@jeremy tak, to był błąd. Jeśli chodzi o przekazywanie przez referencję, to nie jest to, co "*" oznacza - Python nie robi wskaźników takich jak C (* all * przekazywanie argumentów jest bardziej podobne do referencji C++, z tym wyjątkiem, że ponowne przypisanie nazwy nie wpływa na oryginalny obiekt - Dokumenty nazywają to [przekazywanie przez przypisanie] (https://docs.python.org/3/faq/programming.html#how-do-i-write-a-function-with-output-parameters-call-by -reference). * * to sposób działania programu w języku Python - oznacza to, że możesz go nazwać 'min (1,2,3)', itp., jako dowolną liczbą argumentów, i zbierze je wszystkie do postaci lista nazwana 'args'. – lvc

9

operatorów porównania <, <=, >= i > sprawdzić, czy jeden zestaw ścisły podzbiorem, podzbiór, rozszerzeniem lub surowe rozszerzeniem innym, odpowiednio.

{0} i {1} są dla wszystkich z nich False, więc wynik zależy od kolejności kontroli i operatora.

+0

dla '1' i' {0,2} 'dlaczego to zawsze 1? –

8

Kluczowym punktem jest to, że dwa zestawy nie są podzbiorami siebie, więc oba są False dla < mimo że nie są równe:

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

Więc który z nich jest mniejszy? Fakt, że zestawy nie zapewniają strict weak ordering oznacza, że ​​nie ma poprawnej odpowiedzi.

+0

czy możesz powiedzieć, dlaczego '1' <' {0,2} 'w python? –

+4

W języku Python 2.x, różne typy obiektów są porównywane przez ich ciągi znaków, co nie ma dla mnie większego sensu. W języku Python 3.x '1 <{0,2}' jest nielegalne. –

+1

@YuHao Tak, zauważ, że '1 <{0,2}' spowoduje podniesienie typów TypeError: unorderable: int()