Snijd de uiteinden weg
Laat middle een nieuwe lijst zonder eerste en laatste element teruggeven.
Je wilt een wandelroute aanpassen zonder het oorspronkelijke plan kwijt te raken. Soms heb je alleen het middendeel van de route nodig, soms een eigen versie die je kunt uitbreiden. Daarvoor moet je onderscheid maken tussen een tweede naam voor dezelfde lijst en een nieuwe lijst.
Een slice kiest meerdere elementen uit een reeks. Bij stops[1:3] telt de beginpositie één mee en de eindpositie drie niet. Dat sluit aan bij de eindgrens die je al van range kent.
Laat je het begin weg, dan begint de slice bij het begin van de lijst. Laat je het einde weg, dan gaat zij door tot het einde. Met items[1:-1] kies je daarom alles tussen het eerste en laatste element.
Een derde onderdeel bepaalt de stapgrootte. stops[::2] kiest posities nul, twee, vier en verder. De elementen blijven in die gekozen volgorde staan.
Een slice van een lijst levert een nieuwe lijst op. Grenzen buiten de beschikbare posities worden ingekort; een leeg gekozen deel geeft []. Daardoor werkt de slice voor het middendeel ook bij nul, één of twee elementen: er blijft dan niets over.
Een alias is een andere naam die naar hetzelfde object verwijst. Met alias = stops maak je dus geen tweede route. Met copy = stops[:] maak je wel een nieuwe buitenste lijst, met alle huidige elementen.
Druk op Voorbeeld uitvoeren. Kijk eerst naar de twee slices en daarna naar de routes: alleen de kopie krijgt de extra bestemming.
stops = ["brug", "bos", "meer", "dorp"]
alias = stops
copy = stops[:]
copy.append("duin")
print(stops[1:3])
print(stops[::2])
print(alias is stops)
print(copy is stops)
print(stops)
print(copy)['bos', 'meer'] ['brug', 'meer'] True False ['brug', 'bos', 'meer', 'dorp'] ['brug', 'bos', 'meer', 'dorp', 'duin']
De operator is vergelijkt objectidentiteit: gaat het om precies hetzelfde object? De operator == vergelijkt daarentegen inhoud. Twee aparte lijsten kunnen dus gelijk van inhoud zijn en toch niet hetzelfde object zijn.
stops ──┐
├──► lijst A: oorspronkelijke route
alias ──┘
copy ──────► lijst B: route met extra stopHet schema laat namen en lijsten apart zien. Een verandering aan lijst A is via beide bovenste namen zichtbaar. Een verandering aan de buitenste lijst B verandert de buitenste lijst A niet.
Een lijst kan zelf weer lijsten bevatten. Denk aan een buitenste lijst met twee vakjes, waarbij ieder vakje een lijst spullen bevat. Een slice maakt in dat geval een oppervlakkige kopie: alleen de buitenste lijst is nieuw.
Deze zelfstandige foutvariant gaat uit van de verkeerde verwachting dat daarmee ook ieder binnenste vakje is gekopieerd. Voorspel of de gum straks ook in de oorspronkelijke spullenlijst verschijnt.
rows = [["pen"], ["boek"]]
copied = rows[:]
copied[0].append("gum")
print(rows)
print(copied)
print(copied is rows)
print(copied[0] is rows[0])[['pen', 'gum'], ['boek']] [['pen', 'gum'], ['boek']] False True
Beide afgedrukte lijsten bevatten de gum. De buitenste lijsten zijn verschillend, maar hun eerste element verwijst nog naar dezelfde binnenste lijst. Het toevoegen verandert juist die gedeelde binnenste lijst.
rows ──► buitenste lijst A ──┐
├──► hetzelfde eerste vakje
copied ──► buitenste lijst B ──┘Een oppervlakkige kopie kan precies de bedoeling zijn. Zij geeft je een onafhankelijke buitenste volgorde terwijl de elementen gedeeld blijven. Wil je ook binnenste lijsten veranderen zonder terugwerking, dan moet je die eveneens kopiëren; dat werk je later in deze module uit.
De opdrachten oefenen eerst slices en daarna kopiecontracten. Bij een kopie uitbreiden moet de oorspronkelijke buitenste lijst gelijk blijven. Bij de opdracht shallow moeten de binnenste rijen juist dezelfde objecten blijven: maak daar geen volledig losse rijen van.
De tests controleren zowel inhoud als objectidentiteit. Alleen een nieuwe naam kiezen bewijst geen kopie, en alleen een ander object maken bewijst niet dat de juiste elementen zijn overgenomen.
Laat middle een nieuwe lijst zonder eerste en laatste element teruggeven.
Laat every_other posities nul, twee, vier en verder teruggeven.
Laat copy_add een andere lijst teruggeven en de invoerlijst behouden.
Laat shallow een nieuwe buitenste lijst met gedeelde rijen teruggeven.
Hierna pak je reeksen uit in namen en vang je meerdere middelste elementen tegelijk op.
Voer je code uit en ontdek
wat je hebt gemaakt.
Je hoeft het niet in één keer goed te doen. Na het uitvoeren zie je hier welke stappen al kloppen.