5. Listen Listen sind die fundamentalen Datenstrukturen, um in Mathematica Objekte zu gruppieren. Es gibt eine Reihe von built-in Mathematica Funktionen um Listen zu erzeugen und zu manipulieren. Diese sowie die Behandlung Strings sind Gegenstand dieses Kapitels. 5.1 Erzeugung und Darstellung von Listen Listen werden in Mathematica sehr häufig verwendet, siehe auch die verschiedenen Tutorials im DC (tutorial/ListsOverview). Vektoren und Matrizen werden zB einfach als Listen (oder im Falle einer Matrix als "Liste einer Liste") behandelt. Für die Eingabe gibt es zwei Möglichkeiten: entweder über geschwungene Klammern { }, oder über die List-Funktion. Intern sind beide Eingabemöglichkeiten ident (überprüfbar mit FullForm). Die einzelnen Listenelemente sind durch Beistriche voneinander getrennt. 8a, b, c< 8a, b, c< List@a, b, cD 8a, b, c< Es gibt viele Funktionen, die Listen als Ergebnis haben, wie zum Beispiel die bereits bekannte SolveFunktion sol = SolveAx2 1, xE Head@solD 88x ® - 1<, 8x ® 1<< List Mathematica bietet 3 wichtige Funktionen an, mit denen Listen erzeugt werden können: Range, Table, Array. ? Range Range@imax D generates the list 81, 2, … , imax <. Range@imin , imax D generates the list 8imin , … , imax <. Range@imin , imax , diD uses step di. 2 05_Listen.nb Range@10D 81, 2, 3, 4, 5, 6, 7, 8, 9, 10< [email protected], 7D 83.3, 4.3, 5.3, 6.3< 5 RangeB- 2 , 5, 2 :- 5 3 11 ,- 2 7 ,- 6 F 1 ,6 1 , 2 5 , 6 3 , 6 13 , 2 17 , 6 7 , 6 25 , 2 29 , 6 6 > Range ist also eine überladene Funktion, die eine Liste von Zahlen erzeugt, beginnend mit imin bis imax mit der Schrittweite di. Das Zahlentriple 8imin , imax , di< wird auch als Iterator bezeichnet. Die Funktion Table erzeugt eine Liste, deren Elemente vom Iterator abhängen können. ? Table Table@expr, 8imax <D generates a list of imax copies of expr. Table@expr, 8i, imax <D generates a list of the values of expr when i runs from 1 to imax . Table@expr, 8i, imin , imax <D starts with i = imin . Table@expr, 8i, imin , imax , di<D uses steps di. Table@expr, 8i, 8i1 , i2 , … <<D uses the successive values i1 , i2 , … . Table@expr, 8i, imin , imax <, 8 j, jmin , jmax <, … D gives a nested list. The list associated with i is outermost. TableAi2 , 8i, 1, 5, 2<E 81, 9, 25< Elemente einer Liste können selbst wieder Listen sein, was man als verschachtelte (nested) Listen bezeichnet, wie in dem untenstehenden Beispiel: l = 85, 83, 4, 5<, 7, 88, 81, 2<<, 8a, b<<; FullForm@lD List@5, List@3, 4, 5D, 7, List@8, List@1, 2DD, List@a, bDD 05_Listen.nb 3 TreeForm@lD List 5 List 7 3 4 5 List 8 List List 1 a b 2 Durch Verwendung zweier (oder mehrerer) Iteratoren können mit der Table-Funktion verschachtelte Listen erzeugt werden. lis1 = Table@i + j, 8i, 3<, 8j, 4<D 882, 3, 4, 5<, 83, 4, 5, 6<, 84, 5, 6, 7<< innerer Iterator: "Reihe" äußerer Iterator: "Spalte" Mehr Information über die inneren Listen: a = Dimensions@lis1D 83, 4< Solche 2-dimensionalen Listen können auch als Matrix interpretiert werden und mit MatrixForm in Matrixdarstellung angezeigt werden. lis1 MatrixForm 2 3 4 5 3 4 5 6 4 5 6 7 5.2 Arbeiten mit Listen Part and Position Die Extraktion von Elementen einer Liste geschieht mit der Part-Funktion bzw. mit der equivalenten Syntax [[ ]] analog zu der Vorgehensweise, die wir bereits bei der Manipulation von expressions kennengelernt haben. (Listen sind nur spezielle expressions, deren Head eben List ist) 4 05_Listen.nb Die Extraktion von Elementen einer Liste geschieht mit der Part-Funktion bzw. mit der equivalenten Syntax [[ ]] analog zu der Vorgehensweise, die wir bereits bei der Manipulation von expressions kennengelernt haben. (Listen sind nur spezielle expressions, deren Head eben List ist) Clear@a, b, c, dD lis1 = 8a, b, c, d, e, a< 8a, b, c, d, e, a< lis1@@3DD H* das 3. Element der Liste, oder: Part@lis1,3D *L c lis2 = 88a, b, c<, 8d, e, f<, 8g, h, i<<; lis2 MatrixForm a b c d e f g h i lis2@@3, 2DD H* 3. Zeile, 2. Spalte *L h Übung: Das Ziel ist aus einer Liste S={s1, s2, ...} mit n beliebigen Elementen und einer Liste P={p1, p2, ...} mit Zahlen zwischen 1 und n (d.h. einer Permutation von Range[n]) eine neue Liste T={t1,t2,...} zu erzeugen, die die Elemente von S in der durch P vorgegebenen Reihenfolge enthält. Ein Beispiel: S={a, b, c, d} und P={3, 2, 4, 1} Þ T={c, b, d, a} s = 8a, b, c, d< p = 83, 2, 4, 1< 8a, b, c, d< 83, 2, 4, 1< s@@81, 4<DD H* Gibt man bei als Argument von @@...DD eine Liste 8< and, so ist das Ergebnis wieder eine Liste der gewünschten Elemente *L 8a, d< s@@pDD H* Somit ist die Lösung ist ganz einfach!! *L 8c, b, d, a< Die Position-Funktion ermöglicht die Position eines Elements einer Liste festzustellen: 05_Listen.nb ? Position Position@expr, patternD gives a list of the positions at which objects matching pattern appear in expr. Position@expr, pattern, levelspecD finds only objects that appear on levels specified by levelspec. Position@expr, pattern, levelspec, nD gives the positions of the first n objects found. Position@8a, b, c, d, e, a<, aD 881<, 86<< Entfernen von unerwünschten Klammern einer nested list mit dem Befehl Flatten : Flatten@%D 81, 6< Anmerkung : Aufrufen von füheren Zeilen im Notebook % entspricht der letzten Output-Zeile %% vorletzte Output-Zeile %n entspricht der Out[n]-Ausgabe crtl + L fügt eine Kopie die letzte In-Zeile ein ctrl + shift + L fügt eine Kopie der letzten Out-Zeile ein. ? Flatten Flatten@listD flattens out nested lists. Flatten@list, nD flattens to level n. Flatten@list, n, hD flattens subexpressions with head h. Flatten@list, 88s11 , s12 , … <, 8s21 , s22 , … <, … <D flattens list by combining all levels sij to make each level i in the result. Übung: An welchen Positionen befindet sich “9” in der folgenden Liste? {{2, 1, 10}, {9, 5, 7}, {2, 10, 4}, {10, 1, {9}}} lis = 882, 1, 10<, 89, 5, 7<, 82, 10, 4<, 810, 1, 80, 9<<<; lis TableForm 2 9 2 1 5 10 10 1 10 7 4 0 9 Position@lis, 9D 882, 1<, 84, 3, 2<< 5 6 05_Listen.nb Take, Drop, First, Last list = 8a, b, c, d, e, f, g<; ? Take Take@list, nD gives the first n elements of list. Take@list, -nD gives the last n elements of list. Take@list, 8m, n<D gives elements m through n of list. Take@list, seq1 , seq2 , … D gives a nested list in which elements specified by seqi are taken at level i in list. Take@list, 3D 8a, b, c< ? Drop Drop@list, nD gives list with its first n elements dropped. Drop@list, -nD gives list with its last n elements dropped. Drop@list, 8n<D gives list with its nth element dropped. Drop@list, 8m, n<D gives list with elements m through n dropped. Drop@list, 8m, n, s<D gives list with elements m through n in steps of s dropped. Drop@list, seq1 , seq2 , … D gives a nested list in which elements specified by seqi have been dropped at level i in list. Drop@list, 3D 8d, e, f, g< ? First First@exprD gives the first element in expr. First @listD a ? Last Last@exprD gives the last element in expr. Last@listD g 05_Listen.nb ? Rest Rest@exprD gives expr with the first element removed. Rest@listD 8b, c, d, e, f, g< Sort, Reverse, RotateLeft, RotateRight Sortieren: Zahlen der Größe nach, komplexe zuerst nach dem Realteil symbols und strings alphabetisch Potenzen und Produkte wie in einem Polynom expressions der Länge nach Listen nach dem ersten Element 0 list = RandomInteger@81, 100<, 10D H* 10 zufällige Integer-Zahlen zwischen 1 und 10 *L 873, 24, 91, 6, 56, 77, 32, 24, 75, 8< ? Sort Sort@listD sorts the elements of list into canonical order. Sort@list, pD sorts using the ordering function p. Sort@listD 86, 8, 24, 24, 32, 56, 73, 75, 77, 91< Listen umdrehen: ? Reverse Reverse@exprD reverses the order of the elements in expr. Reverse@expr, nD reverses elements at level n in expr. Reverse@expr, 8n1 , n2 , … <D reverses elements at levels n1 , n2 , … in expr. Reverse@listD 88, 75, 24, 32, 77, 56, 6, 91, 24, 73< Listen rotieren: 7 8 05_Listen.nb ? RotateLeft RotateLeft@expr, nD cycles the elements in expr n positions to the left. RotateLeft@exprD cycles one position to the left. RotateLeft@expr, 8n1 , n2 , … <D cycles elements at successive levels ni positions to the left. list RotateLeft@list, 2D RotateRight@list, 2D 873, 24, 91, 6, 56, 77, 32, 24, 75, 8< 891, 6, 56, 77, 32, 24, 75, 8, 73, 24< 875, 8, 73, 24, 91, 6, 56, 77, 32, 24< Partition, Transpose, Dot-Product ? Partition Partition@list, nD partitions list into non-overlapping sublists of length n. Partition@list, n, dD generates sublists with offset d. Partition@list, 8n1 , n2 , … <D partitions a nested list into blocks of size n1 n2 … . Partition@list, 8n1 , n2 , … <, 8d1 , d2 , … <D uses offset di at level i in list. Partition@list, n, d, 8kL , kR <D specifies that the first element of list should appear at position kL in the first sublist, and the last element of list should appear at or after position kR in the last sublist. If additional elements are needed, Partition fills them in by treating list as cyclic. Partition@list, n, d, 8kL , kR <, xD pads if necessary by repeating the element x. Partition@list, n, d, 8kL , kR <, 8x1 , x2 , … <D pads if necessary by cyclically repeating the elements xi . Partition@list, n, d, 8kL , kR <, 8<D uses no padding, and so can yield sublists of different lengths. Partition@list, nlist, dlist, 8klistL , klistR <, padlistD specifies alignments and padding in a nested list. Partition@list, 2D 8873, 24<, 891, 6<, 856, 77<, 832, 24<, 875, 8<< list2 = Partition@list, 5D 8873, 24, 91, 6, 56<, 877, 32, 24, 75, 8<< Transponieren einer Matrix: 05_Listen.nb ? Transpose Transpose@listD transposes the first two levels in list. Transpose@list, 8n1 , n2 , … <D transposes list so that the kth level in list is the nk th level in the result. list2 Transpose@list2D 8873, 24, 91, 6, 56<, 877, 32, 24, 75, 8<< 8873, 77<, 824, 32<, 891, 24<, 86, 75<, 856, 8<< list2 MatrixForm Transpose@list2D MatrixForm K 73 24 91 6 56 O 77 32 24 75 8 73 24 91 6 56 77 32 24 75 8 Matrixmultiplikation wieder mit Dot: ?. a.b.c or Dot@a, b, cD gives products of vectors, matrices, and tensors. v = 8a, b, c<; w = 8c, d, e< v.w H* Skalarprodukt = Dot-Product: Dot@v,wD *L v ´ w H* elementweise Multiplikation *L 8c, d, e< ac+bd+ce 8a c, b d, c e< 9 10 05_Listen.nb A = Array@a, 84, 3<D; H* Matrix mit 4 Zeilen und 3 Spalten *L MatrixForm@AD a@1, a@2, a@3, a@4, 1D 1D 1D 1D a@1, a@2, a@3, a@4, 2D 2D 2D 2D a@1, a@2, a@3, a@4, 3D 3D 3D 3D Clear@vD V = Array@v, 3D; H* Spaltenvektor mit 4 Zeilen *L MatrixForm@VD v@1D v@2D v@3D A.V MatrixForm H* Matrix-Vektor Multiplikation *L a@1, a@2, a@3, a@4, 1D v@1D + a@1, 1D v@1D + a@2, 1D v@1D + a@3, 1D v@1D + a@4, 2D v@2D + a@1, 2D v@2D + a@2, 2D v@2D + a@3, 2D v@2D + a@4, 3D v@3D 3D v@3D 3D v@3D 3D v@3D Übung: Wir betrachten nun das umgekehrte Problem (siehe oben) und wollen aus den Listen T={t1, t2, ...} und P={p1, p2, ...} die neue Liste S={s1, s2, ...} erzeugen, in der t1 das Element an der Position p1 von S ist usw. Also zB: P={3, 2, 4, 1} and T={c, b, d, a} Þ S={a, b, c, d}. p = 83, 2, 4, 1<; t = 8c, b, d, a<; 8p, t< Transpose@8p, t<D Sort@Transpose@8p, t<DD Transpose@Sort@Transpose@8p, t<DDD Transpose@Sort@Transpose@8p, t<DDD@@2DD 883, 2, 4, 1<, 8c, b, d, a<< 883, c<, 82, b<, 84, d<, 81, a<< 881, a<, 82, b<, 83, c<, 84, d<< 881, 2, 3, 4<, 8a, b, c, d<< 8a, b, c, d< Wir fassen die einzelnen Schritte zu einer Funktion zusammen: 05_Listen.nb orderelements@P_, T_D := Transpose@Sort@Transpose@8P, T<DDD@@2DD p = 83, 2, 4, 1<; t = 8c, b, d, a<; orderelements@p, tD 8a, b, c, d< p = 810, 8, 5, 6, 7, 3, 1, 2, 5, 4<; t = 8a, b, c, d, e, f, g, h, i, j<; orderelements@p, tD 8g, h, f, j, c, i, d, e, b, a< Insert, ReplacePart, Append, Prepend Teile einfügen: ? Insert Insert@list, elem, nD inserts elem at position n in list. If n is negative, the position is counted from the end. Insert@expr, elem, 8i, j, … <D inserts elem at position 8i, j, … < in expr. Insert@expr, elem, 88i1 , j1 , … <, 8i2 , j2 , … <, … <D inserts elem at several positions. Insert@lis1, X, 2D 8a, X, b, c, d, e, a< Teile ersetzen: ReplacePart@lis1, X, 2D 8a, X, c, d, e, a< Teile anhängen: Append@lis1, XD 8a, b, c, d, e, a, X< Prepend@lis1, XD 8X, a, b, c, d, e, a< 11 12 05_Listen.nb Join, Union, Intersection, Complement Listen verbinden: ? Join Join@list1 , list2 , … D concatenates lists or other expressions that share the same head. Join@list1 , list2 , … , nD joins the objects at level n in each of the listi . Union ist ähnlich wie Join, nimmt aber gleichzeitig eine Sortierung vor und löscht Elemente, die mehr als einmal vorkommen. ? Union Union@list1 , list2 , … D gives a sorted list of all the distinct elements that appear in any of the listi . Union@listD gives a sorted version of a list, in which all duplicated elements have been dropped. Schnittmenge: ? Intersection Intersection@list1 , list2 , … D gives a sorted list of the elements common to all the listi . Komplementäre Teile von Listen: ? Complement Complement@eall , e1 , e2 , … D gives the elements in eall which are not in any of the ei . 5.3 Strings Die Funktionen zum Manipulieren von Strings weisen Parallelen zu den oben besprochenen Funktionen für Listen auf. Zunächst zwei Beispiele für Strings, die bekanntermaßen durch durch Angabe von Hochkommas “...” eingeschlossen sind "aodsjköasdhjfk" aodsjköasdhjfk a = "Mathematica" Mathematica 05_Listen.nb 13 Head@aD String Viele Funktionen, die wir bereits für Listen kennengelerent haben, exisistieren in leicht veränderter Form (vorangestelltes String im Funktionsnamen) auch für Strings, wie untenstehende Beispiele zeigen solllen. StringLength, StringReverse, StringTake, StringDrop, StringPosition, StringInsert, StringReplace, StringJoin StringLength a H* hier nur zur Erinnerung die PreFix Anwendung einer Funktion *L 11 StringReverse a acitamehtaM StringTake@a, 3D StringDrop@a, 3D StringPosition@a, "a"D StringJoin@a, " Version 9.0"D Mat hematica 882, 2<, 87, 7<, 811, 11<< Mathematica Version 9.0 StringInsertAa, "EINGEFÜGT", 5E StringReplace@a, "a" ® "x"D MathEINGEFÜGTematica Mxthemxticx Mathematica bietet auch Funktionen an, mit den eine String in seine einzelnen Teile (Characters) zerlegt werden kann bzw. ein String in Groß- bzw. Kleinbuchstaben umgewandelt werden kann (ToUpperCase and ToLowerCase) alist = Characters@aD 8M, a, t, h, e, m, a, t, i, c, a< 14 05_Listen.nb Characters liefert also eine Liste der Zeichen eines Strings. alist Head alist@@3DD alist@@3DD Head List t String ToUpperCase@aD MATHEMATICA ToLowerCase@aD mathematica Jeder String kann auch in seinen ASCII code umgewandelt werden mit Hilfe der Funktion ToCharacterCode ToCharacterCode@aD 877, 97, 116, 104, 101, 109, 97, 116, 105, 99, 97< Für den umgekehrten Weg gibt es FromCharacterCode FromCharacterCode@865, 66, 67<D FromCharacterCode@897, 98, 99<D FromCharacterCode@Range@48, 57DD ABC abc 0123456789 A - Z: 65 - 90 a - z: 97 - 122 0 - 9: 48 - 57 ( * difference to upper cases is 32... *) Übungsaufgaben Ü5.1: Schreiben Sie eine Funktion RandList[n], die eine Liste der Länge n mit zufälligen Elementen aus {-1, 0, 1} erzeugt. Ü5.2: RandomWalk in 2D: Schreiben Sie eine Funktion RandWalk2D[n], die eine Liste mit n Schritten erzeugt, wobei bei jedem Zufallsschritt einer der folgende 4 Schritte möglich ist: {1,0}, {-1,0}, {0,1}, oder {0,-1}. 05_Listen.nb 15 Ü5.2: RandomWalk in 2D: Schreiben Sie eine Funktion RandWalk2D[n], die eine Liste mit n Schritten erzeugt, wobei bei jedem Zufallsschritt einer der folgende 4 Schritte möglich ist: {1,0}, {-1,0}, {0,1}, oder {0,-1}. Ü5.3: Erzeuge in maximal 3 Schritten aus der Liste {a, b, c, d, e, f, g} eine neue Liste, die nur die Elemente an den geraden Positionen enthält. (Hinweis: Verwende Partition) Ü5.4: Schreiben Sie eine Funktion OnlyInOne[li1,li2], die aus zwei Listen li1 und li2 diejenigen Elemente herausfindet, die nur in einer der beiden Listen vorkommt. Ein Beispiel: li1= {a,b,c,d} und li2= {a,b,e,f}. Hier wäre das Ergenis {c,d,e,f}, weil diese Elemente nur in einer der beiden Listen vorkommen. Testen Sie Ihre Funktion anhand zweier Listen mit je 40 Zufallszahlen im Bereich zwischen 1 und 20. Ü5.5: Schreiben Sie eine Funktion CaesarEncode[string,n], die eine sogenannte Cäsarverschlüsselung der Zeichenfolge string durchführt. Bei er Cäsarverschlüsselung werden die Buchstaben des Alphabets zyklisch um n Schritte vertauscht. Ein Beispiel zur Verdeutlichung CaesarEncode[string,5] ergibt bei folgendem String: “ABCDEFGHIJKLMNOPQRSTUVWXYZ” “VWXYZABCDEFGHIJKLMNOPQRSTU” Schreiben Sie eine entsprechende Funktion CaesarDecode und versuchen Sie folgenden Text zu entschlüsseln: code = "QVR PNRFNE IREFPUYHRFFRYHAT VFG RVA RVASNPURF FLZZRGEVFPURF IREFPUYHRFFRYHATFIRESNUERA QNF NHS QRE ZBABTENCUVFPURA HAQ ZBABNYCUNORGVFPURA FHOFGVGHGVBA ONFVREG NYF RVARF QRE RVASNPUFGRA HAQ HAFVPUREFGRA IRESNUERA QVRAG RF URHGR UNHCGFNRPUYVPU QNMH TEHAQCEVAMVCVRA QRE XELCGBYBTVR NAFPUNHYVPU QNEMHFGRYYRA";