Example:
{{{id=380| L = [3, Permutation([5,1,4,2,3]), 17, 17, 3, 51] /// }}} {{{id=124| L /// }}} {{{id=273| /// }}}Exercise: Create the list [63, 12, -10, 'a', 12], assign it to the variable L, and print the list.
{{{id=306| /// }}} {{{id=123| /// }}} {{{id=113| /// }}}Exercise: Create the empty list. (You will often need to do this.)
{{{id=112| /// }}} {{{id=79| /// }}}The range function provides an easy way to construct a list of integers. Here is the documentation of the range function.
Docstring:
range([start,] stop[, step]) -> list of integers Return a list containing an arithmetic progression of integers. range(i, j) returns [i, i+1, i+2, ..., j-1]; start (!) defaults to 0. When step is given, it specifies the increment (or decrement). For example, range(4) returns [0, 1, 2, 3]. The end point is omitted! These are exactly the valid indices for a list of 4 elements.
Exercise: Use range to construct the list $[1,2,\ldots,50]$.
{{{id=281| /// }}} {{{id=285| /// }}} {{{id=40| /// }}}Exercise: Use range to construct the list of even numbers between 1 and 100 (including 100).
{{{id=44| /// }}} {{{id=304| /// }}} {{{id=43| /// }}}Exercise: The step argument for the range command can be negative. Use range to construct the list $[10, 7, 4, 1, -2]$.
{{{id=305| /// }}} {{{id=47| /// }}} {{{id=48| /// }}}List comprehensions provide a concise way to create lists from other lists (or other data types).
Example. We already know how to create the list $[1, 2, \ldots, 16]$:
range(1,17)
Using a list comprehension, we can now create the list $[1^2, 2^2, 3^2, ..., 16^2]$ as follows:
[i^2 for i in range(1,17)]
{{{id=119| /// }}} {{{id=118| /// }}} {{{id=130| /// }}} {{{id=129| /// }}}The sum of the squares of the first ten natural numbers is,
12 + 2 2 + ... + 10 2 = 385The square of the sum of the first ten natural numbers is,
(1 + 2 + ... + 10)2 = 55 2 = 3025Hence the difference between the sum of the squares of the first ten natural numbers and the square of the sum is 3025
385 = 2640.
Find the difference between the sum of the squares of the first one hundred natural numbers and the square of the sum.
A list can be filtered using a list comprehension.
Example: To create a list of the squares of the prime numbers between 1 and 100, we use a list comprehension as follows.
Exercise: Use a list comprehension to list all the natural numbers below 20 that are multiples of 3 or 5.
Hints:
{{{id=132| /// }}} {{{id=139| /// }}} {{{id=138| /// }}}
- To get the remainder of 7 divided by 3 use 7%3.
- To test for equality use two equal signs (==); for example, 3 == 7.
List comprehensions can be nested!
Examples:
{{{id=115| [(x,y) for x in range(5) for y in range(3)] /// }}} {{{id=339| [[i^j for j in range(1,4)] for i in range(6)] /// }}} {{{id=144| matrix([[i^j for j in range(1,4)] for i in range(6)]) /// }}} {{{id=352| /// }}} {{{id=114| /// }}}Exercise:
A Pythagorean triple is a triple $(x,y,z)$ of positive integers satisfying $x^2+y^2=z^2$.
The Pythagorean triples whose components are at most $10$ are : $[(3, 4, 5), (4, 3, 5), (6, 8, 10), (8, 6, 10)]$.
Using a filtered list comprehension, construct the list of Pythagorean triples whose components are at most $50$.
{{{id=78| /// }}} {{{id=69| /// }}} {{{id=323| /// }}} {{{id=322| /// }}}To access an element of the list, use the syntax L[i], where i is the index of the item.
Exercise:
{{{id=39| /// }}} {{{id=2| /// }}}
To change the item in position i of a list L:
{{{id=160| L = ["a", 4, 1, 8] /// }}} {{{id=307| L /// }}} {{{id=170| L[2] = 0 /// }}} {{{id=159| L /// }}} {{{id=172| /// }}} {{{id=171| /// }}}To append an object to a list:
{{{id=157| L = ["a", 4, 1, 8] /// }}} {{{id=308| L /// }}} {{{id=173| L.append(17) /// }}} {{{id=174| L /// }}} {{{id=156| /// }}}To extend a list by another list:
{{{id=309| L1 = [1,2,3] L2 = [7,8,9,0] /// }}} {{{id=177| print L1 print L2 /// }}} {{{id=179| L1.extend(L2) /// }}} {{{id=180| L1 /// }}} {{{id=175| /// }}}To concatenate two lists, add them (+). This is not a commutative operation....
{{{id=252| L1 = [1,2,3] L2 = [7,8,9,0] print L1 print L2 /// }}} {{{id=251| L1 + L2 /// }}} {{{id=255| /// }}}You can slice a list using the syntax L[start : stop : step]. This will return a sublist of L.
Exercise: Below are some examples of slicing lists. Try to guess what the output will be before evaluating the cell.
{{{id=262| L = range(20) L /// }}} {{{id=261| L[3:15] /// }}} {{{id=258| L[3:15:2] /// }}} {{{id=266| L[15:3:-1] /// }}} {{{id=264| L[:4] /// }}} {{{id=271| L[:] /// }}} {{{id=270| L[::-1] /// }}} {{{id=269| /// }}}Exercise: The following function combines a loop with the some of the list operations above. What does the function do?
{{{id=276| def f(number_of_iterations): L = [1] for n in range(2, number_of_iterations): L = [sum(L[:i]) for i in range(n-1, -1, -1)] return numerical_approx(2*L[0]*len(L)/sum(L), digits=50) /// }}} {{{id=278| /// }}} {{{id=359| /// }}} {{{id=274| /// }}}A tuple is an immutable list. That is, it cannot be changed once it is created.
The syntax for creating a tuple is to the use parentheses.
{{{id=244| t = (3, 5, [3,1], (17,[2,3],17), 4) t /// }}}We can create a tuple from a list, or vice-versa.
{{{id=301| tuple(range(5)) /// }}} {{{id=372| list(t) /// }}} {{{id=333| /// }}} {{{id=334| /// }}} {{{id=331| /// }}}Tuples behave like lists in many respects:
Operation | Syntax for lists | Syntax for tuples |
Accessing a letter |
list[3] | tuple[3] |
Concatenation | list1 + list2 | tuple1 + tuple2 |
Slicing | list[3:17:2] | tuple[3:17:2] |
A reversed copy |
list[::-1] | tuple[::-1] |
Length | len(list) | len(tuple) |
Trying to modify a tuple will fail.
{{{id=378| t = (5, 'a', 6/5) t /// }}} {{{id=379| t[1] = 'b' /// }}} {{{id=377| /// }}}Generators
"Tuple-comprehension" does not exist. The syntax produces something called a generator. A generator allows you to process a sequence of items one at a time. Each item is created when it is needed, and then forgotten. This can be very efficient if we only need to use each item once.
{{{id=238| (i^2 for i in range(5)) /// }}} {{{id=237| g = (i^2 for i in range(5)) /// }}} {{{id=236| g[0] /// }}} {{{id=235| [x for x in g] /// }}}g is now empty.
{{{id=233| [x for x in g] /// }}}A nice 'pythonic' trick is to use generators as the argument to functions. We do not need double parentheses for this.
{{{id=231| sum( i^2 for i in srange(100001) ) /// }}} {{{id=338| /// }}} {{{id=230| /// }}}A dictionary is another built-in data type. Unlike lists, which are indexed by a range of numbers, dictionaries are "indexed" by keys, which can be any immutable object. Strings and numbers can always be keys (because they are immutable). Dictionaries are sometimes called "associative arrays" in other programming languages.
There are several ways to define dictionaries. One method is to use braces, {}, with comma-separated entries given in the form key:value.
{{{id=360| d = {3:17, "key":[4,1,5,2,3], (3,1,2):"goo", 3/2 : 17} d /// }}}Dictionaries behave as lists and tuples for several important operations.
Operation | Syntax for lists | Syntax for dictionaries |
Accessing elements |
L[3] | D["key"] |
Length | len(L) | len(D) |
Modifying | L[3] = 17 | D["key"] = 17 |
Deleting items | del L[3] | del D["key"] |
A dictionary can have the same value multiple times, but each key can only appear once must be immutable.
{{{id=383| d = {3 : 14, 4: 14} d /// }}} {{{id=384| d = {3: 13, 3:14} d /// }}} {{{id=385| d = {[1,2,3] : 12} d /// }}} {{{id=398| /// }}} {{{id=397| /// }}} {{{id=396| /// }}}Another way to add items to a dictionary is with the update() method:
{{{id=386| d = {} d /// }}} {{{id=362| d.update( {10 : 'newvalue', 20: 'newervalue', 3: 14, 'a':[1,2,3]} ) d /// }}} {{{id=389| /// }}} {{{id=388| /// }}}We can iterate through the keys, or values, or both, of a dictionary.
{{{id=391| d = {10 : 'newvalue', 20: 'newervalue', 3: 14, 'a':[1,2,3]} /// }}} {{{id=363| [key for key in d] /// }}} {{{id=387| [key for key in d.iterkeys()] /// }}} {{{id=364| [value for value in d.itervalues()] /// }}} {{{id=190| [(key, value) for key, value in d.iteritems()] /// }}} {{{id=313| /// }}} {{{id=399| /// }}} {{{id=195| /// }}}Exercise: Consider the following directed graph.
Create a dictionary whose keys are the vertices of the above directed graph, and whose values are the lists of the vertices that it points to. For instance, the vertex 1 points to the vertices 2 and 3, so the dictionary will look like:
d = { ..., 1:[2,3], ... }
Then try
g = DiGraph(d)
g.plot()
Using sage types: The srange command
Example: Construct a $3 \times 3$ matrix whose $(i,j)$ entry is the rational number $\frac{i}{j}$.
{{{id=327| matrix([[ i/j for j in range(1,4)] for i in range(1,4)]) /// }}} {{{id=326| matrix([[ i/j for j in srange(1,4)] for i in srange(1,4)]) /// }}} {{{id=341| srange? /// }}} {{{id=325| srange(.5,3.5,.2) /// }}} {{{id=330| /// }}} {{{id=329| /// }}} {{{id=317| /// }}} {{{id=316| /// }}}Modifying lists has consequences!
Try to predict the results of the following commands.
{{{id=346| a = [1, 2, 3] L = [a, a, a] L /// }}} {{{id=343| a.append(4) L /// }}}Now try these:
{{{id=348| a = [1, 2, 3] L = [a, a, a] L /// }}} {{{id=351| a = [1, 2, 3, 4] L /// }}} {{{id=355| L[0].append(4) L /// }}}You can use the command deepcopy to avoid these issues.
{{{id=356| a = [1,2,3] L = [deepcopy(a), deepcopy(a)] L /// }}} {{{id=357| a.append(4) L /// }}} {{{id=368| /// }}} {{{id=367| /// }}} {{{id=315| /// }}}The same issues occur with dictionaries.
{{{id=314| d = {1:'a', 2:'b', 3:'c'} dd = d d.update( { 4:'d' } ) dd /// }}} {{{id=320| /// }}} {{{id=319| /// }}} {{{id=318| /// }}} {{{id=212| /// }}} {{{id=210| /// }}} {{{id=228| /// }}} {{{id=206| /// }}} {{{id=205| /// }}} {{{id=204| /// }}} {{{id=203| /// }}} {{{id=202| /// }}} {{{id=201| /// }}} {{{id=200| /// }}} {{{id=199| /// }}} {{{id=198| /// }}} {{{id=197| /// }}} {{{id=196| /// }}} {{{id=193| /// }}} {{{id=194| /// }}}