{"id":5540,"date":"2012-09-12T20:48:00","date_gmt":"2012-09-13T00:48:00","guid":{"rendered":"http:\/\/cscircles.cemc.uwaterloo.ca\/?page_id=5540"},"modified":"2024-07-15T04:25:10","modified_gmt":"2024-07-15T08:25:10","slug":"17-de","status":"publish","type":"page","link":"https:\/\/cscircles.cemc.uwaterloo.ca\/dev\/17-de\/","title":{"rendered":"17: Is"},"content":{"rendered":"<p>In dieser Lektion werden wir mehr ins Detail gehen bez\u00fcglich der Frage, wie Python Listen speichert. Listen zu kopieren und zu vergleichen kann unerwartete Konsequenzen haben. Wir werden erkl\u00e4ren, wie Python intern funktioniert, so dass du diese Fehler verstehen und vermeiden kannst. Das Problem im Allgemeinen ist, dass mehrere unterschiedliche Variablen auf dieselbe Liste \"zeigen\" oder dieselbe Liste \"bezeichnen\" k\u00f6nnen. Gegen Ende der Lektion beschreiben wir den \"<code>is<\/code>\" Operator, der uns sagt, ob zwei Variablen <em>wirklich<\/em> auf genau dieselbe Liste verweisen.<\/p>\n<h1>Beispiel<\/h1>\n<p>Nehmen wir zum Beispiel ein Code Fragment, das eine Liste von L\u00e4ngen in Zoll mit dem Namen <code>oldSize<\/code> in eine Liste derselben L\u00e4ngen in Zentimetern mit dem Namen <code>newSize<\/code> konvertiert. Der naheliegende Weg, dies zu erreichen, ist, die Zeile <code>newSize = oldSize<\/code>\u00a0zu benutzen, um eine Kopie zu erzeugen, und sie dann durchzugehen, um alle Werte zu \u00e4ndern:<\/p>\n<pre>oldSize = [\"letter\", 8.5, 11] \u00a0 # Gr\u00f6\u00dfe eines Papiers in Zoll\nnewSize =\u00a0oldSize \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 # erstelle eine Kopie\nnewSize[1] = newSize[1]*2.54 \u00a0 \u00a0# konvertiere in cm\nnewSize[2] = newSize[2]*2.54 \u00a0 \u00a0# konvertiere in cm<\/pre>Jetzt lasst uns sehen, ob das tats\u00e4chlich funktioniert. Wenn man <code>newSize<\/code> ausgibt, bekommt man <code>[\"letter\", 21.59, 27.94]<\/code> wie erwartet. Aber es gibt eine gro\u00dfe \u00dcberraschung, wenn man auch <code>oldSize<\/code> ausgibt: die Werte von <code>oldSize<\/code> haben sich ver\u00e4ndert! Zur Illustration:<\/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>Die zweite Zeile des Outputs ist nicht, was wir erwarten!<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>Wir werden nun im Detail erkl\u00e4ren, was genau passiert ist, mit Hilfe einiger Diagramme. Das Hauptproblem ist, dass <code>newSize = oldSize<\/code> nicht wirklich die vollst\u00e4ndige Liste kopiert hat: es hat nur einen <em>Verweis<\/em>\u00a0(arrow) auf dieselbe Liste kopiert.<\/p>\n<p><em>Klicke auf die Folientitel, um den Tab zu wechseln.<\/em><\/p>\n<div class=\"accordion\"><div class='collapseContain showing'>\n<div class='collapseHead'><span class='icon'><\/span>\nSpeicher\n<\/div>\n<div class='collapseBody'><br \/>\nWir werden eine Tabelle benutzen, um die Variablen und Werte in Pythons Speicher zu repr\u00e4sentieren. Zum Beispiel, nachdem wir folgenden Code laufen lassen<\/p>\n<pre>city = \"Moose Factory\"\npopulation = 2458\nemployer = city<\/pre>zeigt diese Tabelle (mit dem schwarzen Rand) wie Pythons Speicher aussieht:<br \/>\n<img loading=\"lazy\" decoding=\"async\" class=\"alignnone\" src=\"..\/wp-content\/lesson_files\/img\/17\/slide1.png\" alt=\"\" width=\"480\" height=\"141\" \/><\/p>\n<p>Der Name der ersten Variable ist <code>city<\/code> und ihr Wert ist der String <code>\"Moose Factory\"<\/code>. Der Name der zweiten Variable ist <code>population<\/code> und ihr Wert ist die Zahl <code>2458<\/code>. Der Name der dritten Variable ist <code>employer<\/code> und ihr Wert ist der String <code>\"Moose Factory\"<\/code>.<\/div><\/div><br \/>\n<div class='collapseContain hiding'>\n<div class='collapseHead'><span class='icon'><\/span>\nListen im Speicher\n<\/div>\n<div class='collapseBody'><br \/>\nAls n\u00e4chstes zeigen wir, wie eine <em>Liste<\/em> im Speicher aussieht. Nehmen wir zum Beispiel das Code Fragment<\/p>\n<pre>myList = [\"Moose Factory\", 2458]<\/pre>Dies wird nur eine Variable mit dem Namen <code>myList<\/code> erstellen. Eine Liste wird erstellt und der Wert von <code>myList<\/code> wird gesetzt als \u00c4quivalent zu \"zeigen\" oder \"verweisen\" auf diese Liste. Wir repr\u00e4sentieren die Liste mit Hilfe einer Box, und die Werte der Listeneintr\u00e4ge werden in der Box neben den ihnen entsprechenden Indizes angezeigt. Die Liste wird in blau angezeigt.<br \/>\n<img loading=\"lazy\" decoding=\"async\" class=\"alignnone\" src=\"..\/wp-content\/lesson_files\/img\/17\/slide2.png\" alt=\"\" width=\"724\" height=\"202\" \/><\/p>\n<p>Der Pfeil zeigt, dass <code>myList<\/code> auf diese neue Liste verweist. Das Element bei Index 0 auf der Liste ist der String <code>\"Moose Factory\"<\/code>, und das Element bei Index 1 ist die Zahl <code>2458<\/code>. Zum Beispiel, wenn Du <code>print(myList[1])<\/code> schreibst, wird Python <code>2458<\/code> ausgeben.<\/div><\/div><br \/>\n<div class='collapseContain hiding'>\n<div class='collapseHead'><span class='icon'><\/span>\nEinen Listenwert ersetzen\n<\/div>\n<div class='collapseBody'><br \/>\nJetzt f\u00fcgen wir zu Illustrationszwecken eine weitere Zeile zum vorigen Beispiel hinzu. Ein Baby wird geboren, also lassen wir folgendes Codefragment laufen<\/p>\n<pre>myList = [\"Moose Factory\", 2458]\nmyList[1] = myList[1]+1<\/pre>Python berechnet <code>2458+1<\/code> was \u00e4quivalent zu <code>2459<\/code> ist, und dies ersetzt nun den Wert bei Index 1 auf der Liste. Nach dem Update haben wir das unten gezeigte Diagramm.<br \/>\n<img loading=\"lazy\" decoding=\"async\" class=\"alignnone\" src=\"..\/wp-content\/lesson_files\/img\/17\/slide3.png\" alt=\"\" width=\"724\" height=\"202\" \/><\/p>\n<p>(Die <span style=\"text-decoration: line-through;\">2458<\/span> ist kein Teil von Pythons Speicher, sondern ist nur da um die Ver\u00e4nderung hervorzuheben.)<br \/>\n<\/div><\/div><br \/>\n<div class='collapseContain hiding'>\n<div class='collapseHead'><span class='icon'><\/span>\n<code>oldSize<\/code> und <code>newSize<\/code>\n<\/div>\n<div class='collapseBody'>Nun zur\u00fcck zum Hauptbeispiel. Die erste Zeile war<\/p>\n<pre>oldSize = [\"letter\", 8.5, 11]<\/pre>also sieht Pythons Speicher wie das Diagramm unten aus, nachdem diese Zeile ausgef\u00fchrt wurde. Wir haben eine Liste der L\u00e4nge 3 erstellt.<br \/>\n<img loading=\"lazy\" decoding=\"async\" class=\"alignnone\" src=\"..\/wp-content\/lesson_files\/img\/17\/slide4.png\" alt=\"\" width=\"724\" height=\"202\" \/><\/div><\/div><br \/>\n<div class='collapseContain hiding'>\n<div class='collapseHead'><span class='icon'><\/span>\nHauptproblem\n<\/div>\n<div class='collapseBody'>In unserem Programm lautet die zweite Zeile<\/p>\n<pre>newSize = oldSize<\/pre>und hier finden wir tats\u00e4chlich das Hauptproblem: <strong><code>=<\/code> dupliziert die Liste nicht!<\/strong> Stattdessen hat es nur einen neuen Verweis auf <strong>dieselbe<\/strong> Liste kopiert. Dies wird illustriert von zwei unterschiedlichen Pfeilen, die auf genau <strong>dieselbe<\/strong> Box zeigen. Das ist ein ziemlicher Unterschied dazu, Zahlen oder Ausdr\u00fccke zu kopieren (wie auf der ersten Folie).<img loading=\"lazy\" decoding=\"async\" class=\"alignnone\" src=\"..\/wp-content\/lesson_files\/img\/17\/slide5.png\" alt=\"\" width=\"724\" height=\"202\" \/><\/p>\n<p>Wie das Diagramm zeigt, haben wir zwei Variablen, die beide auf dieselbe Liste verweisen.<br \/>\n<\/div><\/div><br \/>\n<div class='collapseContain hiding'>\n<div class='collapseHead'><span class='icon'><\/span>\nUpdaten\n<\/div>\n<div class='collapseBody'>Als n\u00e4chstes, wenn das Programm die Zeile erreicht<\/p>\n<pre>newSize[1] = newSize[1]*2.54<\/pre>Python sieht <code>newSize<\/code>, schl\u00e4gt den Wert von dessen Index 1 nach (8.5) und multipliziert ihn mit 2.54, dann ersetzt es den Wert wie gezeigt. Aber, da <code>oldSize<\/code> sich auf dieselbe Liste bezieht, ist ein Nebeneffekt, dass wir auch <code>oldSize<\/code> modifiziert haben!<br \/>\n<img loading=\"lazy\" decoding=\"async\" class=\"alignnone\" src=\"..\/wp-content\/lesson_files\/img\/17\/slide6.png\" alt=\"\" width=\"724\" height=\"202\" \/><\/p>\n<p>(Wiederum ist <span style=\"text-decoration: line-through;\">8.5<\/span> nicht Teil von Pythons Speicher, sondern wird benutzt, um die Ver\u00e4nderung hervorzuheben.)<br \/>\n<\/div><\/div><br \/>\n<div class='collapseContain hiding'>\n<div class='collapseHead'><span class='icon'><\/span>\nErgebnis\n<\/div>\n<div class='collapseBody'>Die n\u00e4chste Zeile ist \u00e4hnlich,<\/p>\n<pre>newSize[2] = newSize[2]*2.54<\/pre>was auch den anderen Wert in der Liste beeinflusst. Nachdem diese Zeile ausgef\u00fchrt ist, sieht Pythons Speicher aus wie das Diagramm unten.<br \/>\n<img loading=\"lazy\" decoding=\"async\" class=\"alignnone\" src=\"..\/wp-content\/lesson_files\/img\/17\/slide7.png\" alt=\"\" width=\"724\" height=\"202\" \/><\/p>\n<p>Wenn wir nun entweder <code>newSize<\/code> <strong>oder<\/strong> <code>oldSize<\/code> ausgeben, gibt uns Python <code>[\"letter\", 21.59, 27.94]<\/code>.<br \/>\n<\/div><\/div><\/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> Ein anderer Weg sich dieses Beispiel anzusehen, ist, es durch ein <a href=\"\/visualize\">Visualization<\/a> Tool laufen zu lassen. Falls Du das tust, musst Du beachten, dass Listen, anstatt von Pfeilen, mittels ihrer \"ID\" dargestellt werden. Jede Liste lebt gewisserma\u00dfen an einer \"Adresse\", die \u00e4quivalent zu ihrer ID ist; ein Adresswert ist wie ein Pfeil, der auf eine Box an einer ID Adresse zeigt. <\/span><\/td><\/table><\/p>\n<h1>Wie man in Python eine Liste richtig kopiert<\/h1>\n<p>Obwohl es <a class=\"hintlink\"  id=\"hintlink1\"> manchmal n\u00fctzlich ist,<\/a> mehrere Verweise auf die selbe Liste zu haben, ist es hier nicht das, was wir wollen.<\/p>\n<p>Wir geben drei L\u00f6sungen. Sie sind alle mehr oder weniger \u00e4quivalent, aber jede wird dir etwas Neues \u00fcber Python beibringen, also ist es die Zeit wert, alle drei zu lesen.<\/p>\n<h2>Methode 1, Verwendung von <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>Kopieren mit <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[:]     # create a copy\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=\"44a8639fa1434f2e1845c09d1ee8298d\"\/>\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>Oben demonstrieren wir, dass <code>newList = oldList[:]<\/code> eine echte Kopie der alten Liste erstellt. Obwohl diese Syntax seltsam aussieht, ist sie verwandt mit etwas, was wir bereits kennengelernt haben. In der <a href=\"https:\/\/cscircles.cemc.uwaterloo.ca\/7a-de\/\">Lektion zu Strings<\/a> haben wir ein Verfahren vorgestellt, um Teilstrings zu isolieren: <code>string[first:tail]<\/code> gibt uns den Teilstring, der mit dem Index <code>first<\/code> anf\u00e4ngt und mit dem Index <code>tail-1<\/code> endet. Wir hatten erw\u00e4hnt, dass es auch verwendet werden kann, um Teillisten von Listen zu erstellen. Zus\u00e4tzlich,<\/p>\n<ul>\n<li>wenn Du <code>first<\/code> ausl\u00e4sst, nimmt es den Defaultwert von <code>0<\/code>;<\/li>\n<li>wenn Du <code>tail<\/code> ausl\u00e4sst, nimmt es den Defaultwert von <code>len<\/code>\u00a0(die L\u00e4nge der Liste\/des Strings).<\/li>\n<\/ul>\n<p>Was also tats\u00e4chlich passiert, ist dass <code>oldList[:]<\/code> eine neue Teilliste erstellt, allerdings eine, die dieselben Daten enth\u00e4lt wie die Originalliste, also ist es eine neue Kopie.<\/p>\n<h2>Methode 2, Verwendung von <code>copy.copy()<\/code><\/h2>\n<p>Es gibt ein Modul namens <code>copy<\/code>, das mehrere Methoden in Verbindung mit dem Kopieren enth\u00e4lt. Die einfachste ist <code>copy.copy(L)<\/code>: wenn sie auf eine Liste <code>L<\/code> angewandt wird, gibt die Funktion eine echte Kopie von <code>L<\/code> aus.<\/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>Kopieren mit\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)     # create a copy\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=\"4910619f4f5f9cf25b6847df12d1c89b\"\/>\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>Die <code>copy.copy()<\/code> Funktion kann auch f\u00fcr andere Arten von Objekten verwendet werden, aber diese werden hier nicht diskutiert werden.<\/p>\n<h2>Methode 3, Verwendung von\u00a0<code>list()<\/code><\/h2>\n<p>Die letzte Weise, eine echte Kopie zu erstellen, ist die Verwendung der list() Funktion. Normalerweise wird <code>list()<\/code> benutzt, um Daten von anderen Typen in den <code>list<\/code> Typen zu konvertieren. (Zum Beispiel <code>list(\"hello\")<\/code> <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\">konvertiert<\/a> den String \"hello\" in eine Liste mit f\u00fcnf Elementen, jedes davon ein Buchstabe.) Aber wenn Du versuchst, etwas, das bereits eine Liste ist, in eine Liste zu konvertieren, erstellt es einfach eine 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>Kopieren mit\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)     # create a copy\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=\"78fd6910476b10454ad98d4378cf77b2\"\/>\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>Listen als Argumente<\/h2>\n<p>Beachte, dass aufgrund der Art und Weise wie eine Liste funktioniert, jede Funktion, bei der eine Liste als Argument funktioniert, auch tats\u00e4chlich die Inhalte einer Liste ver\u00e4ndern kann. (Du hast dies schon in der <a href=\"http:\/\/cscircles.cemc.uwaterloo.ca\/14-de\/\">replace<\/a>\u00a0\u00dcbung gesehen.)<\/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'>Listenargumente<\/span><\/div>Welche Zahl ist der Output des folgenden Programms?<\/p>\n<pre>def func(list):\n \u00a0\u00a0 list[0] = list[0] + list[1]\n \u00a0\u00a0 list[1] = list[1] + list[0]\ndata = [3, 4]\nfunc(data)\nprint(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\">Korrekt! Innerhalb von <code>func<\/code> \u00e4ndern wir das Element beim Index 0 auf 7, und den Wert beim Index 1 auf 7+4=11. Also haben wir das Ergebnis 7*11.<\/div><\/div>\n<h2>Listen mit Hilfe von <code>is<\/code> vergleichen<\/h2>\n<p>Wann sind zwei Listenvariablen <code>L1<\/code> und <code>L2<\/code> \u00e4quivalent? Es gibt zwei unterschiedliche M\u00f6glichkeiten, diese Frage zu interpretieren:<\/p>\n<ul>\n<li><em>Selbe Identit\u00e4t<\/em>: Zeigen\/Verweisen <code>L1<\/code> und <code>L2<\/code> auf genau dasselbe Listenobjekt?<\/li>\n<li><em>Selbe Werte<\/em>:\u00a0Sind die Inhalte von Liste <code>L1<\/code> \u00e4quivalent zu den Inhalten von Liste <code>L2<\/code>?<\/li>\n<\/ul>\n<p>Es stellt sich heraus, dass in Python der Standard \u00c4quivalenz- oder auch Gleichheitsoperator <code>==<\/code> die <em>Selbe Werte<\/em> Bedeutung hat, wie das folgende Beispiel zeigt.<\/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>Die Bedeutung von <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>\nUm auf <em>Selbe Identit\u00e4t<\/em> hin zu pr\u00fcfen, hat Python den <code>is<\/code> Operator. Wir benutzen diesen Operator genauso wie <code>==<\/code>: die Syntax<\/p>\n<p style=\"text-align: center;\"><code>\u00ablist1\u00bb is\u00a0\u00ablist2\u00bb<\/code><\/p>\n<p>gibt <code>True<\/code> aus, falls die Listen auf dieselbe Liste verweisen und <code>False<\/code>, falls sie auf unterschiedliche Listen Verweisen (sogar wenn diese dieselben Inhalte haben).<\/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>Die Bedeutung von\u00a0<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>Wie oft kommt\u00a0<code>True<\/code>\u00a0im Output dieses Programms vor? (Zeichne ein Diagramm, um den \u00dcberblick zu behalten.)<\/p>\n<pre>list1 = [9, 1, 1]\nlist3 = list(list1)\nlist2 = list1\nlist4 = list3[:]\nlist1[0] = 4\nlist5 = list1\nprint(list1 is list2, list2 is list3, list3 is list4, list4 is list5)\nprint(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\">Korrekt! Die Ausgabe ist<br \/>\n<code>True False False False<\/code><\/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> Du solltest\u00a0<code>is<\/code>\u00a0nicht mit Strings oder Zahlen benutzen, weil == bereits in korrekter Weise \u00c4quivalenz testet, und das Verhalten von\u00a0<code>is<\/code>\u00a0ist <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\">schwer vorherzusagen<\/a> in Bezug auf Strings und Zahlen. <\/span><\/td><\/table><\/p>\n<h2>Verschachtelte lists<\/h2>\n<p>Wir haben bereits die meisten wichtigen Informationen erw\u00e4hnt, aber es gibt noch eine weitere h\u00e4ufige Situation, die es zu erw\u00e4hnen lohnt. Eine <em>geschachtelte Liste<\/em> ist eine Liste innerhalb einer anderen Liste, zum Beispiel<\/p>\n<p style=\"text-align: center;\"><code>sample = [365.25, [\"first\", 5]]<\/code><\/p>\n<p><code><\/code>zeigt eine geschachtelte Liste. Die <em>\u00e4u\u00dfere Liste,<\/em>\u00a0auf die <code>sample<\/code> verweist, hat zwei Elemente; das Element an Index 0 ist eine Gleitpunktzahl (\"float\") und das Element an Index 1 ist die <em>innere Liste<\/em>. Die innere Liste ist <code>[\"first\", 5]<\/code>. (Du kannst auch eine Verschachtelung mit mehreren Ebenen herstellen.) Sobald Du anf\u00e4ngst, verschachtelte Listen zu benutzen, denk daran:<\/p>\n<ul>\n<li>Die drei Methoden von oben auf <code>sample<\/code> anzuwenden, kopiert die \u00e4u\u00dfere Liste, aber nicht die innere Liste. Also <code>copy(sample)[1] is sample[1]<\/code>, was bedeutet, dass die Kopie immernoch einen Verweis auf einen Teil der urspr\u00fcnglichen Liste enth\u00e4lt. Das war vermutlich nicht was Du wolltest. Wenn Du eine echte Kopie auf jeder Ebene machen willst, benutze <code>copy.deepcopy()<\/code>.<\/li>\n<li>Geschachtelte Listen mit <code>==<\/code> zu testen ist relativ intuitiv: Python wendet <code>==<\/code> rekursiv auf jedes Listenelement an. Zum Beispiel <code>[[1, 2], 3]==[[1, 2], 3]<\/code> ist <code>True<\/code>, und <code>[[1, 2], 3]==[1, 2, 3]<\/code> ist <code>False<\/code>, da die ersten Elemente unterschiedlich sind (<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> und rekursive \u00c4quivalenz<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>Du hast diese Lektion abgeschlossen! Das folgende Extramaterial ist freiwillig.<\/p>\n<hr \/>\n<h2>Tupel: <code>(\"immutable\", \"lists\")<\/code><\/h2>\n<p>Wir haben oben erw\u00e4hnt, dass, wenn Du eine Funktion auf eine Liste anwendest, sie die Liste ver\u00e4ndern kann. Manchmal willst Du das unm\u00f6glich machen! Eine L\u00f6sung in Python ist es, <em>Tupel<\/em> zu erstellen,\u00a0die dasselbe wie Listen sind, au\u00dfer, dass sie nicht ver\u00e4ndert werden k\u00f6nnen. Wir sagen Listen sind <em>\"ver\u00e4nderlich\"<\/em> und Tupel sind <em>\"unver\u00e4nderlich\"<\/em>. (Strings und Zahlen sind auch unver\u00e4nderlich.) Das kann eine n\u00fctzliche Strategie sein, um zu verhindern, dass Programmierfehler Listen ver\u00e4ndern, die nicht ge\u00e4ndert werden sollten. Tupel sind beinahe identisch mit Listen, au\u00dfer dass sie runde Klammern benutzen <code>()<\/code> anstatt eckiger Klammern <code>[]<\/code>. Du kannst zwischen Tupeln und Listen konvertieren, indem Du <code>tuple()<\/code> und <code>list()<\/code> benutzt.<\/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>Schlauchtupel<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>Zur <code>\u221e<\/code> und dar\u00fcber hinaus: Selbst-Enthaltung<\/h2>\n<p>Es ist m\u00f6glich, eine Liste zu haben, die sich selbst enth\u00e4lt! Mache einfach eine Liste und dann lasse eines ihrer Elemente auf die ganze Liste zur\u00fcck verweisen:<\/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>Ein zirkul\u00e4rer Verweis<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>Du siehst, dass Pythons Outputgenerator schlau genug ist, zu erkennen, dass die Liste in einer Schleife auf sich selbst zur\u00fcck verweist: er gibt \"<code>...<\/code>\" aus anstatt <code>L<\/code> noch einmal als Ganzes auszugeben, um eine unendliche Schleife zu vermeiden.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In dieser Lektion werden wir mehr ins Detail gehen bez\u00fcglich der Frage, wie Python Listen speichert. Listen zu kopieren und zu vergleichen kann unerwartete Konsequenzen haben. Wir werden erkl\u00e4ren, wie Python intern funktioniert, so dass du diese Fehler verstehen und &hellip; <a href=\"https:\/\/cscircles.cemc.uwaterloo.ca\/dev\/17-de\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":2653,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-5540","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/cscircles.cemc.uwaterloo.ca\/dev\/wp-json\/wp\/v2\/pages\/5540","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\/2653"}],"replies":[{"embeddable":true,"href":"https:\/\/cscircles.cemc.uwaterloo.ca\/dev\/wp-json\/wp\/v2\/comments?post=5540"}],"version-history":[{"count":32,"href":"https:\/\/cscircles.cemc.uwaterloo.ca\/dev\/wp-json\/wp\/v2\/pages\/5540\/revisions"}],"predecessor-version":[{"id":15953,"href":"https:\/\/cscircles.cemc.uwaterloo.ca\/dev\/wp-json\/wp\/v2\/pages\/5540\/revisions\/15953"}],"wp:attachment":[{"href":"https:\/\/cscircles.cemc.uwaterloo.ca\/dev\/wp-json\/wp\/v2\/media?parent=5540"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}