{"id":6181,"date":"2012-11-05T20:38:57","date_gmt":"2012-11-06T01:38:57","guid":{"rendered":"http:\/\/cscircles.cemc.uwaterloo.ca\/?page_id=6181"},"modified":"2016-11-22T00:26:56","modified_gmt":"2016-11-22T05:26:56","slug":"17-is-nl","status":"publish","type":"page","link":"https:\/\/cscircles.cemc.uwaterloo.ca\/dev\/17-is-nl\/","title":{"rendered":"17: Is"},"content":{"rendered":"<p><style>  .wp-tabs img {display: block; margin: auto; border: none; height: 202px;} <\/style>In deze les leggen we meer in detail uit hoe lijsten in Python worden opgeslagen. Het kopi\u00ebren en vergelijken van lijsten kan onverwachte gevolgen hebben. We zullen uitleggen hoe Python intern werkt, waardoor je fouten kunt begrijpen en ze kunt vermijden. In het algemeen is het probleem dat meerdere verschillende variabelen kunnen verwijzen naar ( in het Engels \"point to\" of \"refer to\") dezelfde lijst. Aan het eind van de les beschrijven we de \"<code>is<\/code>\" operator die ons kan vertellen of twee variabelen <em>echt<\/em> naar dezelfde lijst verwijzen.<\/p>\n<h1>Voorbeeld<\/h1>\n<p>Laten we aannemen dat we een programma willen dat een lijst met lengte in inches met de naam <code>oldSize<\/code> naar een lijst met dezelfde lengte, genaamd <code>newSize<\/code>, in cm converteert. De meest voor de hand liggende manier is <code>newSize = oldSize<\/code>\u00a0te gebruiken om een kopie te maken en de lijstelementen vervolgens \u00e9\u00e9n voor \u00e9\u00e9n langs te lopen en die omzetten:<\/p>\n<pre>oldSize = [\"letter\", 8.5, 11] \u00a0 # size of paper in inches\r\nnewSize =\u00a0oldSize \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 # make a copy\r\nnewSize[1] = newSize[1]*2.54 \u00a0 \u00a0# convert to cm\r\nnewSize[2] = newSize[2]*2.54 \u00a0 \u00a0# convert to cm<\/pre>Laten we eens kijken of dit werkt. Wanneer je <code>newSize<\/code> afdrukt dan zie je, zoals verwacht,\u00a0<code>[\"letter\", 21.59, 27.94]<\/code>. Maar er wacht ons een verrassing wanneer we <code>oldSize<\/code> printen: de waarden van <code>oldSize<\/code> zijn ook veranderd! Ter illustratie:<\/p>\n<p><form class=\"pbform\" action=\"#\" id=\"pbform0\" method=\"POST\">\n<div class='pybox modeNeutral  facultative' id='pybox0'>\n<div class=\"heading\"><span class=\"title\">Example<\/span><\/div>De tweede regel van de output is niet wat we hadden verwacht!<div class='pyboxTextwrap pyboxCodewrap RO '  style='height: 162px;'><textarea wrap='off' name='usercode0' id='usercode0'  cols=10 rows=6 readonly='readonly'  style = 'height : 162px;'  class='pyboxCode RO'>\noldSize = [\"letter\", 8.5, 11]   # size of paper in inches\nnewSize = oldSize               # make a copy?\nnewSize[1] = newSize[1]*2.54    # convert to cm\nnewSize[2] = newSize[2]*2.54    # convert to cm\nprint(newSize)                  # as expected, prints [\"letter\", 21.59, 27.94]\nprint(oldSize)                  # no longer holds [\"letter\", 8.5, 11]...<\/textarea><\/div>\n<div id='pbhistory0' class='flexcontain' style='display:none;'><\/div>\n<div class='pyboxbuttons'><table><tr>\n<td><input type='submit' name='submit' id='submit0' value=' '\/><\/td>\n<td><input type='button' name='consolecopy' value=\"Open in console\" onclick=\"pbConsoleCopy(0)\" ><\/td>\n<td><input type='button' name='visualize' value=\"Visualize\" onclick=\"pbVisualize(0,'N')\" ><\/td>\n<\/tr><\/table><\/div>\n<input type=\"hidden\" name=\"lang\" value=\"\"\/><input type=\"hidden\" id=\"inputInUse0\" name=\"inputInUse\" value=\"Y\"\/>\n<input type=\"hidden\" name=\"pyId\" value=\"0\"\/>\n<input type=\"hidden\" name=\"hash\" value=\"494a411afbf4e7d2f944e2fdac6f0d61\"\/>\n<div id='pbresults0' class='pbresults'><\/div>\n<\/div>\n<\/form>\n<script type='text\/javascript'>document.getElementById(\"submit0\").value = \"Run program\";document.getElementById(\"inputInUse0\").value = \"N\";<\/script>\n<\/p>\n<p>We zullen nu gedetailleerd, door middel van diagrammen, uitleg geven over wat er gebeurde. Het voornaamste probleem is dat \u00a0<code>newSize = oldSize<\/code>\u00a0niet echt de hele lijst kopieert: het kopieerde slechts een\u00a0<em>verwijzing<\/em>\u00a0(pijl) naar dezelfde lijst.<\/p>\n<p><em>Klik op de schuiftitels om de tabs te openen en te sluiten.<\/em><\/p>\n<div class=\"accordion\"><div class='collapseContain showing'>\n<div class='collapseHead'><span class='icon'><\/span>\nGeheugen\n<\/div>\n<div class='collapseBody'><br \/>\nWe zullen een tabel gebruiken om de variabelen en hun waarden in het geheugen van Python weer te geven. Na het uitvoeren van\u00a0 het programma<\/p>\n<pre>city = \"Moose Factory\"\r\npopulation = 2458\r\nemployer = city<\/pre>wordt in de tabel\u00a0 (met de zwarte rand) getoond hoe het geheugen van Python eruit ziet:<br \/>\n<img decoding=\"async\" src=\"..\/wp-content\/lesson_files\/img\/17\/slide1.png\" alt=\"\" \/>De naam van de eerste variabele is <code>city<\/code> en zijn waarde is de string <code>\"Moose Factory\"<\/code>. De naam van de tweede variabele is <code>population<\/code> en zijn waarde is het gehele getal <code>2458<\/code>. De naam van de derde variabele\u00a0 is <code>employer<\/code> en zijn waarde is de string <code>\"Moose Factory\"<\/code>.<\/div><\/div><br \/>\n<div class='collapseContain hiding'>\n<div class='collapseHead'><span class='icon'><\/span>\nLijsten in het geheugen\n<\/div>\n<div class='collapseBody'><br \/>\nVervolgens laten we zien hoe een <em>lijst<\/em> er in het geheugen uit ziet. Neem als voorbeeld de programmaregel<\/p>\n<pre>myList = [\"Moose Factory\", 2458]<\/pre>Dit zal \u00e9\u00e9n variabele aanmaken met de naam <code>myList<\/code>. Er wordt een lijst aangemaakt, en de waarde van <code>myList<\/code> is gelijk aan het\u00a0 \"wijzen\" of \"verwijzen\" naar die lijst. We representeren de lijst door gebruik te maken van een box, en de waarden van de elementen worden in de box getoond naast hun corresponderende indices. De lijst wordt in het blauw getoond.<br \/>\n<img decoding=\"async\" src=\"..\/wp-content\/lesson_files\/img\/17\/slide2.png\" alt=\"\"  \/>De pijl laat zien dat <code>myList<\/code> verwijst naar deze nieuwe lijst. Het element met index 0 van de lijst is de string <code>\"Moose Factory\"<\/code>, en het element met index 1 is het gehele getal <code>2458<\/code>. Als je bijvoorbeeld <code>print(myList[1])<\/code> dan zal Python <code>2458<\/code> uitvoeren.<\/div><\/div><br \/>\n<div class='collapseContain hiding'>\n<div class='collapseHead'><span class='icon'><\/span>\nEen waarde in een lijst vervangen\n<\/div>\n<div class='collapseBody'><br \/>\nNu zullen we, ter illustratie, een extra regel toevoegen aan het vorige voorbeeld. Omdat er een baby is bijgekomen voeren we de volgende extra regels uit:<\/p>\n<pre>myList = [\"Moose Factory\", 2458]\r\nmyList[1] = myList[1]+1<\/pre>Python berekent <code>2458+1<\/code> en dat is gelijk aan <code>2459<\/code>. Dit wordt de waarde die op index 1 in de lijst staat. Na de update krijgen we het diagram zoals hieronder weergegeven.<br \/>\n<img decoding=\"async\" src=\"..\/wp-content\/lesson_files\/img\/17\/slide3.png\" alt=\"\" \/>(2458 is niet een deel van het geheugen van Python, we laten het zien om de verandering te benadrukken)<br \/>\n<\/div><\/div><br \/>\n<div class='collapseContain hiding'>\n<div class='collapseHead'><span class='icon'><\/span>\n<code>oldSize<\/code> en <code>newSize<\/code>\n<\/div>\n<div class='collapseBody'><br \/>\nNu keren we terug naar het centrale voorbeeld. De eerste regel is<\/p>\n<pre>oldSize = [\"letter\", 8.5, 11]<\/pre>en Pythons geheugen ziet er, nadat deze regel is uitgevoerd, uit als in het diagram beneden. We hebben een lijst van lengte 3 gemaakt.<br \/>\n<img decoding=\"async\" src=\"..\/wp-content\/lesson_files\/img\/17\/slide4.png\" alt=\"\"  \/><\/div><\/div><br \/>\n<div class='collapseContain hiding'>\n<div class='collapseHead'><span class='icon'><\/span>\nCentrale probleem\n<\/div>\n<div class='collapseBody'><br \/>\nIn het programma is de tweede regel<\/p>\n<pre>newSize = oldSize<\/pre>en hier komen we tot het belangrijkste punt: in de tweede regel\u00a0maakt <strong><code>=<\/code>\u00a0geen kopie van de lijst!<\/strong>\u00a0Het maakte slechts een nieuwe verwijzing naar <strong>dezelfde<\/strong> lijst. Dit wordt ge\u00efllustreerd door de twee verschillende pijlen die naar exact <strong>dezelfde<\/strong>\u00a0box verwijzen. Dit verschilt nogal van hoe getallen en strings worden gekopieerd (zoals in de eerste slide).<img decoding=\"async\" src=\"..\/wp-content\/lesson_files\/img\/17\/slide5.png\" alt=\"\"  \/> Het diagram laat zien dat we twee variabelen hebben, die naar dezelfde lijst verwijzen.<\/p>\n<p><\/div><\/div><br \/>\n<div class='collapseContain hiding'>\n<div class='collapseHead'><span class='icon'><\/span>\nUpdaten\n<\/div>\n<div class='collapseBody'>Wanneer vervolgens het programma bij de regel<\/p>\n<pre>newSize[1] = newSize[1]*2.54<\/pre>komt, gaat Python naar\u00a0<code>newSize<\/code>, naar de waarde met index 1 (8.5) en vermenigvuldigt dit met 2.54, en plaatst de waarde terug zoals te zien valt. Omdat\u00a0<code>oldSize<\/code>\u00a0naar dezelfde lijst verwijst wordt ook\u00a0<code>oldSize<\/code> aangepast!<br \/>\n<img decoding=\"async\" src=\"..\/wp-content\/lesson_files\/img\/17\/slide6.png\" alt=\"\" \/>(Voor de duidelijkheid: 8.5 maakt geen deel uit van het geheugen van Python, maar we laten het zien om de verandering te benadrukken.)<br \/>\n<\/div><\/div><br \/>\n<div class='collapseContain hiding'>\n<div class='collapseHead'><span class='icon'><\/span>\nResultaat\n<\/div>\n<div class='collapseBody'><br \/>\nDe volgende regel van het programma lijkt op de vorige,<\/p>\n<pre>newSize[2] = newSize[2]*2.54<\/pre>waarmee de andere waarde van de lijst wordt aangepast. Nadat deze regel is uitgevoerd ziet het geheugen van Python eruit zoals in het diagram hieronder wordt weergegeven.<br \/>\n<img decoding=\"async\" src=\"..\/wp-content\/lesson_files\/img\/17\/slide7.png\" alt=\"\"  \/><\/p>\n<p>Of we nu <code>newSize<\/code> <strong>of<\/strong> <code>oldSize<\/code> printen, Python geeft als output <code>[\"letter\", 21.59, 27.94]<\/code>.<br \/>\n<\/div><\/div><br \/>\n<\/div><br \/>\n<table class='pywarn'><tr><td class='pywarnleft'><img src='https:\/\/cscircles.cemc.uwaterloo.ca\/dev\/wp-content\/plugins\/pybox\/files\/warning.png'\/><\/td><td class='pywarnright'><span> Er is nog een manier om naar dit voorbeeld te kijken. Namelijk door dit voorbeeld te bekijken in de\u00a0<a href=\"\/visualize\">Visualization<\/a> tool. Merk op dat je in plaats van de pijlen de lijsten een naam krijgen via hun \"ID.\" Elke lijst wordt bewaard op een \"adres\" dat gelijk is aan de ID; een adres is als een pijl die naar de box wijst met dat ID. <\/span><\/td><\/table><\/p>\n<h1>Hoe op correcte wijze een lijst in Python te kopi\u00ebren<\/h1>\n<p>Hoewel het <a class=\"hintlink\"  id=\"hintlink1\">soms nuttig<\/a> is om meerdere verwijzingen te hebben naar dezelfde lijst, is dat hier niet wat we willen.<\/p>\n<p>We zullen drie oplossingen bespreken. Ze lijken op elkaar, maar in elke oplossing komt een nieuw aspect van Python aan de orde. Ze zijn dus alle drie de moeite waard om door te werken.<\/p>\n<h2>Methode 1, gebruik\u00a0<code>[:]<\/code><\/h2>\n<p><form class=\"pbform\" action=\"#\" id=\"pbform2\" method=\"POST\">\n<div class='pybox modeNeutral  facultative' id='pybox2'>\n<div class=\"heading\"><span class=\"title\">Example<\/span><\/div>Een kopie maken met <code>[:]<\/code><div class='pyboxTextwrap pyboxCodewrap RO '  style='height: 110px;'><textarea wrap='off' name='usercode2' id='usercode2'  cols=10 rows=4 readonly='readonly'  style = 'height : 110px;'  class='pyboxCode RO'>\noldList = [\"first\", \"second\", \"third\"]\nnewList = oldList[:]     # maak een kopie\noldList.reverse()\nprint(newList, oldList)<\/textarea><\/div>\n<div id='pbhistory2' class='flexcontain' style='display:none;'><\/div>\n<div class='pyboxbuttons'><table><tr>\n<td><input type='submit' name='submit' id='submit2' value=' '\/><\/td>\n<td><input type='button' name='consolecopy' value=\"Open in console\" onclick=\"pbConsoleCopy(2)\" ><\/td>\n<td><input type='button' name='visualize' value=\"Visualize\" onclick=\"pbVisualize(2,'N')\" ><\/td>\n<\/tr><\/table><\/div>\n<input type=\"hidden\" name=\"lang\" value=\"\"\/><input type=\"hidden\" id=\"inputInUse2\" name=\"inputInUse\" value=\"Y\"\/>\n<input type=\"hidden\" name=\"pyId\" value=\"2\"\/>\n<input type=\"hidden\" name=\"hash\" value=\"8577615f9d13aecc2cdd4f31f7fff1f0\"\/>\n<div id='pbresults2' class='pbresults'><\/div>\n<\/div>\n<\/form>\n<script type='text\/javascript'>document.getElementById(\"submit2\").value = \"Run program\";document.getElementById(\"inputInUse2\").value = \"N\";<\/script>\n<\/p>\n<p>Hierboven lieten we zien dat <code>newList = oldList[:] <\/code>wel een echte kopie van de oude lijst maakt. Hoewel de syntax wat vreemd oogt, is het een zusje van iets wat we eerder zagen. In de <a href=\"\/7a-strings\/\">les over strings<\/a> introduceerden we een manier\u00a0om uit een string een substring te halen: <code>string[first:tail]<\/code>\u00a0geeft als resultaat een substring die begint met de index <code>first<\/code>\u00a0en eindigt met index <code>tail-1<\/code>. We noemden al dat het gebruikt kan worden om een deellijst van een lijst te bepalen. In het bijzonder;<\/p>\n<ul>\n<li>wanneer\u00a0<code>first<\/code> wordt weggelaten wordt de standaardwaarde\u00a0<code>0<\/code>\u00a0genomen;<\/li>\n<li>wanneer\u00a0<code>tail<\/code> wordt weggelaten wordt\u00a0de standaardwaardewaarde\u00a0<code>len(..)<\/code>\u00a0(de lengte van de lijst\/string) genomen.<\/li>\n<\/ul>\n<p>Wat hier dus eigenlijk gebeurt is dat\u00a0<code>oldList[:]<\/code>\u00a0een nieuwe sublijst maakt die precies dezelfde data bevat als de originele lijst. Dat is natuurlijk in feite een nieuwe kopie.<\/p>\n<h2>Methode 2, gebruik\u00a0<code>copy.copy()<\/code><\/h2>\n<p>Er is een module met de naam copy met\u00a0meerdere methoden die met kopi\u00ebren\u00a0te maken hebben. De meest eenvoudige is\u00a0<code>copy.copy(L)<\/code>: wanneer je dit aanroept op een lijst <code>L<\/code>, zal de functie een echte kopie van\u00a0<code>L<\/code> teruggeven.<\/p>\n<p><form class=\"pbform\" action=\"#\" id=\"pbform3\" method=\"POST\">\n<div class='pybox modeNeutral  facultative' id='pybox3'>\n<div class=\"heading\"><span class=\"title\">Example<\/span><\/div>Een kopie maken met\u00a0<code>copy.copy<\/code><div class='pyboxTextwrap pyboxCodewrap RO '  style='height: 136px;'><textarea wrap='off' name='usercode3' id='usercode3'  cols=10 rows=5 readonly='readonly'  style = 'height : 136px;'  class='pyboxCode RO'>\nimport copy\noldList = [\"first\", \"second\", \"third\"]\nnewList = copy.copy(oldList)     # maak een kopie\noldList.reverse()\nprint(newList, oldList)<\/textarea><\/div>\n<div id='pbhistory3' class='flexcontain' style='display:none;'><\/div>\n<div class='pyboxbuttons'><table><tr>\n<td><input type='submit' name='submit' id='submit3' value=' '\/><\/td>\n<td><input type='button' name='consolecopy' value=\"Open in console\" onclick=\"pbConsoleCopy(3)\" ><\/td>\n<td><input type='button' name='visualize' value=\"Visualize\" onclick=\"pbVisualize(3,'N')\" ><\/td>\n<\/tr><\/table><\/div>\n<input type=\"hidden\" name=\"lang\" value=\"\"\/><input type=\"hidden\" id=\"inputInUse3\" name=\"inputInUse\" value=\"Y\"\/>\n<input type=\"hidden\" name=\"pyId\" value=\"3\"\/>\n<input type=\"hidden\" name=\"hash\" value=\"08a525f9ee6cae69afa04324b00a9d22\"\/>\n<div id='pbresults3' class='pbresults'><\/div>\n<\/div>\n<\/form>\n<script type='text\/javascript'>document.getElementById(\"submit3\").value = \"Run program\";document.getElementById(\"inputInUse3\").value = \"N\";<\/script>\n<\/p>\n<p>De\u00a0<code>copy.copy()<\/code> functie werkt ook op andersoortige objecten, maar we zullen daar hier niet verder op in gaan.<\/p>\n<h2>Methode 3, gebruik\u00a0<code>list()<\/code><\/h2>\n<p>De laatste manier om een echte kopie te maken is door middel van list() functie. Normaal wordt <code>list()<\/code>\u00a0gebruikt om data van een ander type te vertalen naar het <code>lijst<\/code>-type. (Zo <a href=\"https:\/\/cscircles.cemc.uwaterloo.ca\/dev\/console\/?consolecode=L%20%3D%20list%28%27hello%27%29%0Aprint%28type%28L%29%29%0Aprint%28L%29%0Aprint%28L%5B0%5D%29%0Aprint%28type%28L%5B0%5D%29%29\" target=\"_blank\">vertaalt<\/a> <code>list(\"hello\")<\/code> de string \"hello\" in een lijst met 5 elementen, waarbij elk element \u00e9\u00e9n enkel karakter is.) Maar als je probeert een lijst om te zetten in een lijst, dan maakt het effectief een kopie.<\/p>\n<p><form class=\"pbform\" action=\"#\" id=\"pbform4\" method=\"POST\">\n<div class='pybox modeNeutral  facultative' id='pybox4'>\n<div class=\"heading\"><span class=\"title\">Example<\/span><\/div>Een kopie maken met\u00a0<code>list()<\/code><div class='pyboxTextwrap pyboxCodewrap RO '  style='height: 110px;'><textarea wrap='off' name='usercode4' id='usercode4'  cols=10 rows=4 readonly='readonly'  style = 'height : 110px;'  class='pyboxCode RO'>\noldList = [\"first\", \"second\", \"third\"]\nnewList = list(oldList)     # maak een kopie\noldList.reverse()\nprint(newList, oldList)<\/textarea><\/div>\n<div id='pbhistory4' class='flexcontain' style='display:none;'><\/div>\n<div class='pyboxbuttons'><table><tr>\n<td><input type='submit' name='submit' id='submit4' value=' '\/><\/td>\n<td><input type='button' name='consolecopy' value=\"Open in console\" onclick=\"pbConsoleCopy(4)\" ><\/td>\n<td><input type='button' name='visualize' value=\"Visualize\" onclick=\"pbVisualize(4,'N')\" ><\/td>\n<\/tr><\/table><\/div>\n<input type=\"hidden\" name=\"lang\" value=\"\"\/><input type=\"hidden\" id=\"inputInUse4\" name=\"inputInUse\" value=\"Y\"\/>\n<input type=\"hidden\" name=\"pyId\" value=\"4\"\/>\n<input type=\"hidden\" name=\"hash\" value=\"158c7895146ba572cee0ede29eb5c200\"\/>\n<div id='pbresults4' class='pbresults'><\/div>\n<\/div>\n<\/form>\n<script type='text\/javascript'>document.getElementById(\"submit4\").value = \"Run program\";document.getElementById(\"inputInUse4\").value = \"N\";<\/script>\n<\/p>\n<h2>Lijsten als argumenten<\/h2>\n<p>We merken op dat vanwege de manier waarop lijsten werken,\u00a0 iedere functie die een lijst als argument accepteert, de inhoud van een lijst kan veranderen. (Je kon dat al zien in de\u00a0<code><a href=\"\/14-methods\/\">replace<\/a><\/code>-oefening.)<\/p>\n<p><div class='pybox modeNeutral' id='pybox5'>\n<img title='You have not yet completed this problem.' src='https:\/\/cscircles.cemc.uwaterloo.ca\/dev\/wp-content\/plugins\/pybox\/files\/icon.png' class='pycheck'\/><div class=\"heading\"><span class='type'>Short Answer Exercise: <\/span><span class='title'>Lijst argument<\/span><\/div>Welk getal is output van het volgende programma? <\/p>\n<pre>def func(list):<br\/> \u00a0\u00a0 list[0] = list[0] + list[1]<br\/> \u00a0\u00a0 list[1] = list[1] + list[0]<br\/>data = [3, 4]<br\/>func(data)<br\/>print(data[0]*data[1])<\/pre><label for=\"pyShortAnswer5\">Your answer (enter a number): <\/label><input type=\"text\" onkeypress=\"{if (event.keyCode==13) pbShortCheck(5)}\" id=\"pyShortAnswer5\"><div class=\"pyboxbuttons\"><input type=\"hidden\" name=\"type\" value=\"number\"\/><input type=\"hidden\" name=\"correct\" value=\"77\"\/><input type=\"hidden\" name=\"slug\" value=\"17.reference\"\/><input type=\"hidden\" name=\"lang\" value=\"\"\/><input type='submit' style='margin:5px;' value='Check answer' onClick = 'pbShortCheck(5)'\/><\/div><div class=\"pbresults\" id=\"pyShortResults5\"><\/div><div class=\"epilogue\">Correct! Binnen <code>func<\/code> veranderen we het element met index 0 in 7, en het element met index 1 in 7+4=11. Dus printen we 7*11.<\/div><\/div>\n<h2>Lijsten vergelijken door middel van\u00a0<code>is<\/code><\/h2>\n<p>Wanneer zijn twee lijsten\u00a0<code>L1<\/code>\u00a0en\u00a0<code>L2<\/code> gelijk? We kunnen deze vraag op twee manieren interpreteren:<\/p>\n<ul>\n<li><em>Dezelfde lijst<\/em>: Wijzen <code>L1<\/code> en\u00a0<code>L2<\/code> naar exact hetzelfde lijst-object?<\/li>\n<li><em>Dezelfde waarden<\/em>: Is de inhoud van lijst <code>L1<\/code> gelijk aan de inhoud van lijst <code>L2<\/code>?<\/li>\n<\/ul>\n<p>Nu blijkt dat in Python de standaard gelijkheids-operator <code>==<\/code>\u00a0 <em>Dezelfde waarden <\/em>betekenis heeft, zoals in het volgende voorbeeld laat zien.<\/p>\n<p><form class=\"pbform\" action=\"#\" id=\"pbform6\" method=\"POST\">\n<div class='pybox modeNeutral  facultative' id='pybox6'>\n<div class=\"heading\"><span class=\"title\">Example<\/span><\/div>De betekenis van <code>==<\/code><div class='pyboxTextwrap pyboxCodewrap RO '  style='height: 84px;'><textarea wrap='off' name='usercode6' id='usercode6'  cols=10 rows=3 readonly='readonly'  style = 'height : 84px;'  class='pyboxCode RO'>\nL1 = ['text', 11]\nL2 = L1[:]        # make a copy\nprint(L1 == L2)   # Same Values?<\/textarea><\/div>\n<div id='pbhistory6' class='flexcontain' style='display:none;'><\/div>\n<div class='pyboxbuttons'><table><tr>\n<td><input type='submit' name='submit' id='submit6' value=' '\/><\/td>\n<td><input type='button' name='consolecopy' value=\"Open in console\" onclick=\"pbConsoleCopy(6)\" ><\/td>\n<td><input type='button' name='visualize' value=\"Visualize\" onclick=\"pbVisualize(6,'N')\" ><\/td>\n<\/tr><\/table><\/div>\n<input type=\"hidden\" name=\"lang\" value=\"\"\/><input type=\"hidden\" id=\"inputInUse6\" name=\"inputInUse\" value=\"Y\"\/>\n<input type=\"hidden\" name=\"pyId\" value=\"6\"\/>\n<input type=\"hidden\" name=\"hash\" value=\"14c5779912209a08ee35289f5365c74a\"\/>\n<div id='pbresults6' class='pbresults'><\/div>\n<\/div>\n<\/form>\n<script type='text\/javascript'>document.getElementById(\"submit6\").value = \"Run program\";document.getElementById(\"inputInUse6\").value = \"N\";<\/script>\n<\/p>\n<p>Om <em>Dezelfde lijst <\/em>te testen heeft Python de <code>is<\/code> operator. We gebruiken deze operator op dezelfde manier als <code>==<\/code>: de syntax<\/p>\n<p><code>\u00ablist1\u00bb is\u00a0\u00ablist2\u00bb<\/code><\/p>\n<p>geeft <code>True<\/code> wanneer de variabelen naar dezelfde lijst verwijzen, en <code>False<\/code> wanneer zij naar verschillende lijsten verwijzen (ook al hebben die dezelfde inhoud).<\/p>\n<p><form class=\"pbform\" action=\"#\" id=\"pbform7\" method=\"POST\">\n<div class='pybox modeNeutral  facultative' id='pybox7'>\n<div class=\"heading\"><span class=\"title\">Example<\/span><\/div>De betekenis van <code>is<\/code><div class='pyboxTextwrap pyboxCodewrap RO '  style='height: 162px;'><textarea wrap='off' name='usercode7' id='usercode7'  cols=10 rows=6 readonly='readonly'  style = 'height : 162px;'  class='pyboxCode RO'>\nL = ['text', 11]\nLAgain = L             # another reference to L\nprint(LAgain is L)     # Same Identity? Yes\nLCopy = L[:]           # make a copy\nprint(LCopy == LAgain) # Same Values?   Yes, both are ['text', 11]\nprint(LCopy is LAgain) # Same Identity? No: LAgain is L, but LCopy is not L<\/textarea><\/div>\n<div id='pbhistory7' class='flexcontain' style='display:none;'><\/div>\n<div class='pyboxbuttons'><table><tr>\n<td><input type='submit' name='submit' id='submit7' value=' '\/><\/td>\n<td><input type='button' name='consolecopy' value=\"Open in console\" onclick=\"pbConsoleCopy(7)\" ><\/td>\n<td><input type='button' name='visualize' value=\"Visualize\" onclick=\"pbVisualize(7,'N')\" ><\/td>\n<\/tr><\/table><\/div>\n<input type=\"hidden\" name=\"lang\" value=\"\"\/><input type=\"hidden\" id=\"inputInUse7\" name=\"inputInUse\" value=\"Y\"\/>\n<input type=\"hidden\" name=\"pyId\" value=\"7\"\/>\n<input type=\"hidden\" name=\"hash\" value=\"9b852f7b5486e559e1a1d08b0086a52b\"\/>\n<div id='pbresults7' class='pbresults'><\/div>\n<\/div>\n<\/form>\n<script type='text\/javascript'>document.getElementById(\"submit7\").value = \"Run program\";document.getElementById(\"inputInUse7\").value = \"N\";<\/script>\n<\/p>\n<p><div class='pybox modeNeutral' id='pybox8'>\n<img title='You have not yet completed this problem.' src='https:\/\/cscircles.cemc.uwaterloo.ca\/dev\/wp-content\/plugins\/pybox\/files\/icon.png' class='pycheck'\/><div class=\"heading\"><span class='type'>Short Answer Exercise: <\/span><span class='title'>True Count<\/span><\/div>Hoe vaak komt <code>True<\/code> voor in de output van dit programma? (Teken een diagram om je met tellen te helpen.) <\/p>\n<pre>list1 = [9, 1, 1]<br\/>list3 = list(list1)<br\/>list2 = list1<br\/>list4 = list3[:]<br\/>list1[0] = 4<br\/>list5 = list1<br\/>print(list1 is list2, list2 is list3, list3 is list4, list4 is list5)<br\/>print(list1 == list2, list2 == list3, list3 == list4, list4 == list5)<\/pre><label for=\"pyShortAnswer8\">Your answer (enter a number): <\/label><input type=\"text\" onkeypress=\"{if (event.keyCode==13) pbShortCheck(8)}\" id=\"pyShortAnswer8\"><div class=\"pyboxbuttons\"><input type=\"hidden\" name=\"type\" value=\"number\"\/><input type=\"hidden\" name=\"correct\" value=\"3\"\/><input type=\"hidden\" name=\"slug\" value=\"17.is\"\/><input type=\"hidden\" name=\"lang\" value=\"\"\/><input type='submit' style='margin:5px;' value='Check answer' onClick = 'pbShortCheck(8)'\/><\/div><div class=\"pbresults\" id=\"pyShortResults8\"><\/div><div class=\"epilogue\">Correct! Het resultaat is True False True False<\/div><\/div>\n<p><table class='pywarn'><tr><td class='pywarnleft'><img src='https:\/\/cscircles.cemc.uwaterloo.ca\/dev\/wp-content\/plugins\/pybox\/files\/warning.png'\/><\/td><td class='pywarnright'><span> Je moet niet zonder meer <code>is<\/code> gebruiken met strings of getallen omdat == al op correcte wijze de gelijkheid test, en het gedrag van <code>is<\/code>\u00a0is <a href=\"https:\/\/cscircles.cemc.uwaterloo.ca\/dev\/console\/?consolecode=%23%20why%20is%20%22is%22%20tricksy%20for%20strings%3F%0Aprint%28%22foo%22%20is%20%22foo%22%2C%20%22foo%22%20is%20%22fo%22%2B%22o%22%29%20%23%20both%20True%2C%20due%20to%20string%20interning%0Aprint%28%22e%22%2A32%20is%20%22ee%22%2A16%29%20%23%20False%2C%20long%20strings%20are%20not%20interned%0AA%20%3D%20%22foo%22%0AB%20%3D%20%22foofoo%22%0AA%20%2A%3D%202%0Aprint%28A%20%3D%3D%20B%2C%20A%20is%20B%29%20%23%20True%20False%3A%20%2A%3D%20does%20not%20re-intern%20a%20string%0A%0A%23%20why%20is%20%22is%22%20tricksy%20for%20numbers%3F%0Aprint%281%2B1%20is%202%29%20%23%20True%2C%20but%20this%20behaviour%20is%20only%20for%20small%20ints%0Aprint%2810%2A%2A3%20is%201000%29%20%23%20False%0Aprint%281.5%20is%201.5%2C%201.5%20is%200.5%2A3%29%20%23%20True%2C%20False%0Aprint%28float%28%27NaN%27%29%3D%3Dfloat%28%27NaN%27%29%2C%20float%28%27NaN%27%29%20is%20float%28%27NaN%27%29%29%20%23%20both%20False%0Ax%20%3D%20float%28%27NaN%27%29%0Aprint%28x%20is%20x%2C%20x%20%3D%3D%20x%29%20%23%20True%20False%3B%20one%20of%20few%20examples%20with%20%27is%27T%2C%20%3D%3DF%0Aprint%280.0%20is%200%2C%200.0%20%3D%3D%200%29%20%23%20False%20True%0A%0A%23also%2C%20%22is%22%20not%20same%20as%20compare%20id%28%29%20http%3A%2F%2Fcodepad.org%2FXb0TaKl9%0A%0A\" target=\"_blank\">moeilijk te voorspellen<\/a> bij strings en getallen. <\/span><\/td><\/table><\/p>\n<h2>Geneste lijsten<\/h2>\n<p>We hebben de meest belangrijke informatie nu wel gegeven, maar er is nog een veelvoorkomende situatie waarvan het waard is die te melden. Een <em>geneste lijst<\/em> is een lijst binnen een andere lijst. Bijvoorbeeld<\/p>\n<p><code>sample = [365.25, [\"first\", 5]]<\/code><\/p>\n<p><code><\/code>laat een geneste lijst zien. De <em>buitenste lijst,<\/em>\u00a0waar <code>sample<\/code> naar verwijst, heeft twee elementen; het element met index 0 is een decimaal getal en het element op index 1 is de <em>inwendige lijst<\/em>. De binnenste lijst is <code>[\"first\", 5]<\/code>. Je kunt dus meer niveaus hebben. Wanneer je geneste lijsten begint te gebruiken, houdt dan voor ogen dat:<\/p>\n<ul>\n<li>Wanneer we de drie methodes toepassen op <code>sample<\/code> dan zal de buitenste lijst gekopieerd worden, maar niet de binnenste lijst. Dus <code>copy(sample)[1] is sample[1]<\/code>, betekent dat copy nog steeds een verwijzing bevat naar een deel van de originele lijst. Dit is niet altijd wat je wilt. Wanneer je een echte kopie wilt maken op alle niveaus, gebruik je <code>copy.deepcopy()<\/code>.<\/li>\n<li>Lijsten testen met <code>==<\/code> is intu\u00eftief: Python voert <code>==<\/code> uit op elk element van de lijst. Zo is bijvoorbeeld\u00a0 <code>[[1, 2], 3]==[[1, 2], 3]<\/code> <code>True<\/code>, en <code>[[1, 2], 3]==[1, 2, 3]<\/code> is <code>False<\/code> want de eerste elementen zijn verschillend (<code>[1, 2] != 1<\/code>).<\/li>\n<\/ul>\n<p><form class=\"pbform\" action=\"#\" id=\"pbform9\" method=\"POST\">\n<div class='pybox modeNeutral  facultative' id='pybox9'>\n<div class=\"heading\"><span class=\"title\">Example<\/span><\/div><code>deepcopy<\/code> and recursive equality<div class='pyboxTextwrap pyboxCodewrap RO '  style='height: 266px;'><textarea wrap='off' name='usercode9' id='usercode9'  cols=10 rows=10 readonly='readonly'  style = 'height : 266px;'  class='pyboxCode RO'>\nimport copy\nsample = [365.25, [\"first\", 5]]\nclone = copy.copy(sample)\nprint(sample, clone)\nprint(sample == clone, sample is clone)\nprint(sample[1] == clone[1], sample[1] is clone[1])\ndeepclone = copy.deepcopy(sample)\nprint(deepclone)\nprint(sample == deepclone, sample is deepclone)\nprint(sample[1] == deepclone[1], sample[1] is deepclone[1])<\/textarea><\/div>\n<div id='pbhistory9' class='flexcontain' style='display:none;'><\/div>\n<div class='pyboxbuttons'><table><tr>\n<td><input type='submit' name='submit' id='submit9' value=' '\/><\/td>\n<td><input type='button' name='consolecopy' value=\"Open in console\" onclick=\"pbConsoleCopy(9)\" ><\/td>\n<td><input type='button' name='visualize' value=\"Visualize\" onclick=\"pbVisualize(9,'N')\" ><\/td>\n<\/tr><\/table><\/div>\n<input type=\"hidden\" name=\"lang\" value=\"\"\/><input type=\"hidden\" id=\"inputInUse9\" name=\"inputInUse\" value=\"Y\"\/>\n<input type=\"hidden\" name=\"pyId\" value=\"9\"\/>\n<input type=\"hidden\" name=\"hash\" value=\"9e283f578fffcb8094b88d7e64992baa\"\/>\n<div id='pbresults9' class='pbresults'><\/div>\n<\/div>\n<\/form>\n<script type='text\/javascript'>document.getElementById(\"submit9\").value = \"Run program\";document.getElementById(\"inputInUse9\").value = \"N\";<\/script>\n<\/p>\n<p>Je hebt nu deze les afgerond!\u00a0 Het volgende materiaal is optioneel.<\/p>\n<hr \/>\n<h2>Tuples: <code>(\"immutable\", \"lists\")<\/code><\/h2>\n<p>We noemden hierboven dat wanneer je een functie aanroept die werkt op een lijst het die lijst kan veranderen. Soms wil je dit onmogelijk maken! Een oplossing in Python is om <em>tuples<\/em> te maken. Tuples zijn in principe hetzelfde als lijsten, behalve dat ze niet veranderd kunnen worden. We zeggen dat lijsten <em>\"veranderbaar\"<\/em> zijn, en tuples <em>\"onveranderbaar\" <\/em>. (Strings en getallen zijn ook onveranderbaar.) Dit kan een nuttige manier zijn om programmeerfouten die te maken hebben met het veranderen van lijsten te voorkomen. Tuples zijn qua syntax bijna identiek aan lijsten, behalve dat bij tuples ronde haakjes <code>()<\/code> worden gebruikt in plaats van rechte haken <code>[]<\/code>. Je kunt tuples in lists omzetten en vice versa door middel van de functies <code>tuple()<\/code> en <code>list()<\/code>.<\/p>\n<p><form class=\"pbform\" action=\"#\" id=\"pbform10\" method=\"POST\">\n<div class='pybox modeNeutral  facultative' id='pybox10'>\n<div class=\"heading\"><span class=\"title\">Example<\/span><\/div>Tubular tuples<div class='pyboxTextwrap pyboxCodewrap RO '  style='height: 188px;'><textarea wrap='off' name='usercode10' id='usercode10'  cols=10 rows=7 readonly='readonly'  style = 'height : 188px;'  class='pyboxCode RO'>\nT = (3, 4, 5)\nprint(T)\nprint(type(T))           # tuple\nprint(T[0])              # the first item in the tuple\nprint(list(T))           # converting a tuple to a list\nprint(tuple([1, 2, 3]))  # converting a list to a tuple\nT[0] = \"three\"           # Error! You can't change tuple values<\/textarea><\/div>\n<div id='pbhistory10' class='flexcontain' style='display:none;'><\/div>\n<div class='pyboxbuttons'><table><tr>\n<td><input type='submit' name='submit' id='submit10' value=' '\/><\/td>\n<td><input type='button' name='consolecopy' value=\"Open in console\" onclick=\"pbConsoleCopy(10)\" ><\/td>\n<td><input type='button' name='visualize' value=\"Visualize\" onclick=\"pbVisualize(10,'N')\" ><\/td>\n<\/tr><\/table><\/div>\n<input type=\"hidden\" name=\"lang\" value=\"\"\/><input type=\"hidden\" id=\"inputInUse10\" name=\"inputInUse\" value=\"Y\"\/>\n<input type=\"hidden\" name=\"pyId\" value=\"10\"\/>\n<input type=\"hidden\" name=\"hash\" value=\"7f077bc933194d6bbab91e4d6feb3a5a\"\/>\n<div id='pbresults10' class='pbresults'><\/div>\n<\/div>\n<\/form>\n<script type='text\/javascript'>document.getElementById(\"submit10\").value = \"Run program\";document.getElementById(\"inputInUse10\").value = \"N\";<\/script>\n<\/p>\n<h2>Naar <code>\u221e<\/code> en verder:\u00a0 een lijst die zichzelf bevat<\/h2>\n<p>Het is mogelijk om een lijst te hebben die zichzelf bevat! Maak eenvoudigweg een lijst, en zorg er dan voor dat \u00e9\u00e9n van zijn elementen verwijst naar de hele lijst:<\/p>\n<p><form class=\"pbform\" action=\"#\" id=\"pbform11\" method=\"POST\">\n<div class='pybox modeNeutral  facultative' id='pybox11'>\n<div class=\"heading\"><span class=\"title\">Example<\/span><\/div>Een circulaire referentie<div class='pyboxTextwrap pyboxCodewrap RO '  style='height: 136px;'><textarea wrap='off' name='usercode11' id='usercode11'  cols=10 rows=5 readonly='readonly'  style = 'height : 136px;'  class='pyboxCode RO'>\nL = [\"zero\", \"one\"]\nL[1] = L\nprint(len(L))\nprint(L)\nprint(L is L[1])<\/textarea><\/div>\n<div id='pbhistory11' class='flexcontain' style='display:none;'><\/div>\n<div class='pyboxbuttons'><table><tr>\n<td><input type='submit' name='submit' id='submit11' value=' '\/><\/td>\n<td><input type='button' name='consolecopy' value=\"Open in console\" onclick=\"pbConsoleCopy(11)\" ><\/td>\n<td><input type='button' name='visualize' value=\"Visualize\" onclick=\"pbVisualize(11,'N')\" ><\/td>\n<\/tr><\/table><\/div>\n<input type=\"hidden\" name=\"lang\" value=\"\"\/><input type=\"hidden\" id=\"inputInUse11\" name=\"inputInUse\" value=\"Y\"\/>\n<input type=\"hidden\" name=\"pyId\" value=\"11\"\/>\n<input type=\"hidden\" name=\"hash\" value=\"ef2417b9b7c2f2b395ad4f54e60f4005\"\/>\n<div id='pbresults11' class='pbresults'><\/div>\n<\/div>\n<\/form>\n<script type='text\/javascript'>document.getElementById(\"submit11\").value = \"Run program\";document.getElementById(\"inputInUse11\").value = \"N\";<\/script>\n<\/p>\n<p>Merk op dat Pythons output engine slim genoeg is om te herkennen dat de lijst terug naar zichzelf gaat: het drukt af\u00a0 \"<code>...<\/code>\", en print niet de inhoud van <code>L<\/code> opnieuw. Dit natuurlijk om een oneindige lus te voorkomen..<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In deze les leggen we meer in detail uit hoe lijsten in Python worden opgeslagen. Het kopi\u00ebren en vergelijken van lijsten kan onverwachte gevolgen hebben. We zullen uitleggen hoe Python intern werkt, waardoor je fouten kunt begrijpen en ze kunt &hellip; <a href=\"https:\/\/cscircles.cemc.uwaterloo.ca\/dev\/17-is-nl\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-6181","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/cscircles.cemc.uwaterloo.ca\/dev\/wp-json\/wp\/v2\/pages\/6181","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/cscircles.cemc.uwaterloo.ca\/dev\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/cscircles.cemc.uwaterloo.ca\/dev\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/cscircles.cemc.uwaterloo.ca\/dev\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/cscircles.cemc.uwaterloo.ca\/dev\/wp-json\/wp\/v2\/comments?post=6181"}],"version-history":[{"count":27,"href":"https:\/\/cscircles.cemc.uwaterloo.ca\/dev\/wp-json\/wp\/v2\/pages\/6181\/revisions"}],"predecessor-version":[{"id":9682,"href":"https:\/\/cscircles.cemc.uwaterloo.ca\/dev\/wp-json\/wp\/v2\/pages\/6181\/revisions\/9682"}],"wp:attachment":[{"href":"https:\/\/cscircles.cemc.uwaterloo.ca\/dev\/wp-json\/wp\/v2\/media?parent=6181"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}