2015-01-26 23 views
5

Niedawno poszłam na rozmowę kwalifikacyjną na stanowisko programisty w Pythonie. Poniższy kod był jednym z pytań. Po prostu musiałem napisać wynik.Czy ktoś może wyjaśnić mi ten naprawdę podstawowy kod Pythona?

def extendList(val,list=[]): 
    list.append(val) 
    return list 

list1 = extendList(10) 
list2 = extendList(123,[]) 
list3 = extendList('a') 

print "list1 = %s " %list1 
print "list2 = %s " %list2 
print "list2 = %s " %list3 

Wyjście jest:

list1 = [10, 'a'] 
list2 = [123] 
list2 = [10, 'a'] 

Próbuję zrozumieć, dlaczego pierwsza lista, list1 ma wartość 'a'.

EDIT

Sprawdziłem wszystkie linki i okazało się jego pytona „haczyka” dla początkujących, ale chcę podziękować odpowiedzi, can not wybierać zarówno tak mam zamiar z pierwszej.

+1

[ Ta odpowiedź kanoniczna] (http://stackoverflow.com/questions/1132941/least-astonishment-in-python-the-mutable-default-argument) powinna pomóc –

+0

Duplikat http://stackoverflow.com/q uestions/1132941/najmniej-zdziwienie-w-python-the-mutable-default-argument – davidism

+3

To, że jest inaczej sformułowane, nie czyni z niego innego pytania. – davidism

Odpowiedz

1

list1 ma 'a' ponieważ lista stworzona z extendlist('a') jest dołączenie do tej samej listy, jak extendList(10)

Jest to niewątpliwie wynikiem szczegółowych w sposób zajmuje Pythona z domyślnych argumentów i jest to model państwa. Można nawet argumentować, że jest to błąd, ponieważ narusza właściwość zamknięcia (jeśli metody Pythona mają być zamykane).

Na przykład odpowiednikiem kodu w języku Ruby:

def extendList(val, list=[]) 
    list << val 
    return list 
end 

powraca

extendList(10) 
# => [10] 

extendList(123, []) 
# => [123] 

extendList('a') 
# => ['a'] 

Jest to przypadek w Ruby ponieważ metody Ruby są zamknięcia, czyli każde wezwanie metoda niesie wokół jego własny lokalny środowisko.

+1

. . .i 'print' nie stanie się dopóki wszystkie 3' extendList's nie zostaną ocenione. – WAF

1

Właściwie, to nie jest tak prosty, że to trochę pułapki Pythona: Mutable Default Parameter

porównać z drukowaniem po każdym wywołaniu funkcji:

>>> def extendList(val,list=[]): 
...  list.append(val) 
...  return list 
... 
>>> list1 = extendList(10) 
>>> print "list1 = %s " %list1 
list1 = [10] 
>>> list2 = extendList(123,[]) 
>>> print "list2 = %s " %list2 
list2 = [123] 
>>> list3 = extendList('a') 
>>> print "list2 = %s " %list3 
list2 = [10, 'a'] 

też:

>>> list1 is list2 
False 
>>> list1 is list3 
True 
+0

patrz, z tym kodem nie dostaję "a" na pierwszej liście. WTF. jeje – NachoMiguel

Powiązane problemy