len av en lista
Hej,
Jag gjorde precis en gammal tentamen och stötte på denna fråga:
def f(x):
if len(x) == 0:
return 0
else:
return sum(x) + f(x[1:])
a = [1,2,4]
print (f(a))
Edit: Svaret på denna blir 17, jag förstår att sum(a) = 7 men jag förstår inte varför f(x[1:]) = 10, hur tänker man på den? Tack på förhand!
Tycker också att det verkar märkligt. Funktionen du skrivit verkar ju korrekt. Det kan ha att göra med att du "tabbat" in raden
a = [1,2,4]
och då kanske python tolkar det som att den är en del av funktionen ovan. Testa att dra in den till vänstra kanten.
Att raderna är indenterade (börjar med space/tab) innebär att raderna
a = [1,2,4]
print (f(a))
är inuti själva funktionen. Funktionen körs därför aldrig - är det det som menas med att resultatet är "ingenting"?
Aha, nu ändrades uppgiftsformuleringen. 17 är ett rimligare svar, om funktionen kallas på det sätt man ser ut att vilja =)
x[1:] gör en ny lista av alla element utom det första. Så anropet f([1,2,4]) ger raden
return sum([1,2,4]) + f([2,4])
sum-anropet ger 7, och sen lägger man på f([2,4]). För att beräkna värdet av det kallas funktionen en gång till, med en kortare lista. Det anropet leder i sin tur till
return sum([2,4]) + f([4])
Här går man in ytterligare en nivå, funktionen kallas alltså en tredje gång. Så här fortsätter det tills funktionen i något steg anropas och return-ar utan att kalla sig själv. Vad händer om du följer kedjan hela vägen?
Skaft skrev:Aha, nu ändrades uppgiftsformuleringen. 17 är ett rimligare svar, om funktionen kallas på det sätt man ser ut att vilja =)
x[1:] gör en ny lista av alla element utom det första. Så anropet f([1,2,4]) ger raden
return sum([1,2,4]) + f([2,4])
sum-anropet ger 7, och sen lägger man på f([2,4]). För att beräkna värdet av det kallas funktionen en gång till, med en kortare lista. Det anropet leder i sin tur till
return sum([2,4]) + f([4])
Här går man in ytterligare en nivå, funktionen kallas alltså en tredje gång. Så här fortsätter det tills funktionen i något steg anropas och return-ar utan att kalla sig själv. Vad händer om du följer kedjan hela vägen?
Precis, jag upptäckte själv att jag använt fel indentering på koden så justerade detta. Tusen tack för hjälpen! Tänker man på det sättet som du har skrivit det så blir ju svaret 17, då sum[a] = 7 och f([2,4]) = 10, vilket är helt korrekt.
Jag antar att det är kolonet som gör att a[1:] = [2,4] och inte [2]?
Ja, kolonet gör en slice, vilket skapar en ny lista från en del av den första (man "klipper ut" ett stycke, fast utan att något tas bort ur den första listan). a[2:5] t.ex. gör en ny lista med elementen från index 2, 3 och 4 (övre gränsen 5 inkluderas inte). Skippar man stopp-indexet som i a[1:] tar den helt enkelt alla element från och med startindexet 1. Man kan också skippa startindexet och skriva a[:2] för att ta "alla element innan index 2". Skippar man båda index och skriver a[:] gör man en kopia av hela listan =)
Skaft skrev:Ja, kolonet gör en slice, vilket skapar en ny lista från en del av den första (man "klipper ut" ett stycke, fast utan att något tas bort ur den första listan). a[2:5] t.ex. gör en ny lista med elementen från index 2, 3 och 4 (övre gränsen 5 inkluderas inte). Skippar man stopp-indexet som i a[1:] tar den helt enkelt alla element från och med startindexet 1. Man kan också skippa startindexet och skriva a[:2] för att ta "alla element innan index 2". Skippar man båda index och skriver a[:] gör man en kopia av hela listan =)
Tusen tack igen Skaft, detta ökade min förståelse om detta!