tisdag 11 december 2012

Övningar med listor

Alla positiva heltal som inte själva är primtal går att dela upp i produkter av primtal. Detta kallas primtalsuppdelning. Ex: 28 = 2*2*7, 72 = 2*2*2*3*3, 39 = 3*13

Detta kan bland annat användas för att göra listor på primtal och för att göra snabbare funktion för att finna största gemensamma delare.

Övning 2.13
Lägg till en funktion till modulen diskret_matematik för  att skapa en funktion som utför primtalsuppdelning enligt nedanstående pseudokod:

def primtalsuppdelning(n):
    Skapa en tom lista kallad primtal
    sätt variabeln p till 2
    så länge som p är mindre eller lika med n:
        om n är jämnt delbart med p:
            lägg till p i listan primtal
            dividera n med p
        annars :
            öka p med ett
            
    returnera primtal

Övning 2.14
Använd primtalsuppdelningen ovan till att göra en betydligt effektivare version av funktionen sgd(a, b). Byt ut den befintliga mot denna version. Pseudokod:

def sgd(a, b):
    sätt storst till det största talet av a och b samt
    minst till det minsta
        
    om storst jämnt delbart med minst returnera minst
    primtalsuppdela minst och spara resultatet i listan prim
    antag att största gemensamma delare, sgd är 1
    för alla tal p i prim :
        om storst jämnt delbart med p :
            dela storst med p
            multiplicera sgd med p
            
    returnera sgd


Övning 2.15
Uppdatera main() i diskret_matematik med tester av primtalsuppdelningen och testkör.

Uppgift 2.5
Skriv ett program som hittar primtal genom att använda Eratosthenes såll.
Bild: Wikipedia

onsdag 5 december 2012

Mer om listor

Forsatsen och listor

Om du inte behöver veta indexet kan du använda dig av for-satsens förmåga att iterera över listor.

Övning 2.9

lista = ["Hej", "alla", "glada"]

for e in lista :
    print(e, end = " ")

 Listor är objekt

Listor är objekt i Python. Det skiljer dem från tal och strängar. Objekt är behållare för variabler och även i många fall metoder. Deras innehåll kan förändras utan att skapa ett nytt objekt.

Jämför hur du lade ihop två textsträngar med:

s = s + t

du inte kan förändra strängen s utan måste skapa en ny sträng som sedan ersätter den gamla i s. Med hur du lägger till en lista till en annan lista:

li.extend(li2)

I detta fall läggs elementen i li2 till de i listan li direkt. Detta då li är ett objekt som  innehåller ett antal element.

Namnen på objekt kallas identifierare då de namnger ett unikt objekt.

Till skillnad mot strängar är listor alltså ändringsbara efter det de skapats. Du kan ändra de ingående elementen i listan.

Övning 2.10
Skriv och testa nedanstående program

lista = [1, 2, 3, 4]
lista[0] = 5
lista[1] = lista[3]
lista[3] lista[3]/2
print(lista)

OBS! Objekt överförs via referens
Den viktigaste skillnaden mellan variabler och objekt är att variabler överförs via värdet och objekt via referens.

Övning 2.11
Skriv in nedanstående program och testa. Notera resultatet. Vad händer här?

s = "Hej"
t = s
t = t + " på dej."
print("Variabler")
print ("s="+s)
print ("t="+t)

li = ["Hej"]
li2 = li
li2.extend(["på","dej"])
print("Objekt")
print ("li="+str(li))
print ("li2="+str(li2))

För strängarna så har s kvar sitt värde ("Hej") när t förändrats. För listobjekten förändras även li när li2 ändras. Det beror på att li2 = li gör att båda identifierarna refererar till samma objekt. Se figuren nedan:


Ovanstående skillnad är speciellt viktigt när du använder objekt som argument i funktioner. Du kan skriva funktioner som gör förändringar i det objekt som ges som funktionsargument. Ex:

Övning 2.12
Följande funktion byter ut element i en lista. Element som är lika med bort byts ut mot element som anges i till

def bytut(li, bort, till):
    #Byter ut elementet i bort mot det i till i listan li
    for i in range(len(li)) :
        if li[i] == bort :
            li[i]=till

lista = [1, 2, 3, 4, 2]          
bytut(lista, 2, 8)
print(lista)

Notera att ingen return-sats behövs i funktionen då den arbetar via referens med listan som ges i argumentet.

Kopior av listor
Ibland vill du ha en kopia av en lista som du kan arbeta med. Alltså skapa ett nytt listobjekt med samma innehåll som det ursprungliga. Då kan du använda en for-sats och iterera över ursprungliga listans element. Följande skapar en ny lista li2 och fyller den med elementen i li:

li2 = []
for e in li : li2.append(e)

Listor och strängar
Listor kan även innehålla strängar och strängar kan omvandlas till listor av tecken.

För att omvandla en sträng till en teckenlista används li = list(s) där s är den sträng som skall delas upp.

För att omvandla en lista med tecken eller strängar till en sträng används s.join(li) där s är ursprungssträgen och li innehåller de tecken som ska läggas till. Följande ger text="abc":

li = ["a", "b", "c"]
text = "".join(li)

Uppgift 2.4
Skriv din egen vändnings-funktion som byter ordningen för elementen i en lista av tal eller strängar. Se nedanstående pseudokod.

def reversera(lista):
    medan index, i, mindre än halva listlängden
        spara temporärt värdet för elementet i från slutet
        sätt värdet på elementet i från slutet till det för i från början
        sätt värdet på elementet i från början till det sparade värdet
        öka i med ett