forked from ninas/umonya_notes
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathlists.html
More file actions
677 lines (544 loc) · 21.2 KB
/
lists.html
File metadata and controls
677 lines (544 loc) · 21.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Introductory Programming in Python: Lists</title>
<link rel='stylesheet' type='text/css' href='style.css' />
<meta http-equiv='Content-Type' content='text/html; charset=utf-8' />
<script src="animation.js" type="text/javascript">
</script>
</head>
<body onload="animate_loop()">
<div class="page">
<h1>Introductory Programming in Python: Lesson 8<br />
Lists</h1>
<div class="centered">
[<a href="while_loops.html">Prev: Flow Control: Conditional Loops</a>] [<a href="index.html">Course Outline</a>] [<a href="tuples.html">Next: Tuples</a>]
</div>
<h2>The Necessity of Lists</h2>
<p>Let us for the sake of originality work on a new problem.</p>
<blockquote class='problem'>
A lecturer for an introductory programming course wants to record
some information about his students. He wants to keep a record of
each student's name, their primary field of study, and a brief
description of their current research project. He would like to be
able to print this out in a nicely formatted way. His class has 19
students.
</blockquote>
<p>For each student we need to record their name, field of study, and a
description of their research project. This means three values we need
to store for each student, or 38 variables in total. Surely there's a
better way. There is, and python yet again provides us with the perfect
tool for job, <a class="doclink"
href="http://olympiad.cs.uct.ac.za/docs/python-docs-2.6/library/stdtypes.html#typesseq">the list</a>!</p>
<p>A list is a <strong>type</strong> of variable. To create a new
variable of type list in python simply assign a variable to a list.
Lists are formed using square brackets surrounding a comma separated
sequence of the elements of the list. Example:</p>
<pre class='listing'>
>>> mylist = [1, 2, 3]
>>> anotherlist = ["Alice", "Bob", "Carl", "Mallory"]
>>> mixed = ["a string", 143, [341]]
>>> empty = []
>>>
</pre>
<ul>
<li>Lists contain elements, e.g. 'mylist' contains three elements,
namely 1, 2, and 3.</li>
<li>Lists have length, being the number of elements they contain,
e.g. 'mylist' has length 3, 'anotherlist' has length 4</li>
<li>We can determine the length of a list using python's built in
<a class="doclink"
href="http://olympiad.cs.uct.ac.za/docs/python-docs-2.6/library/functions.html#len">len
function</a>
<pre class='listing'>
>>> len([1, 2, 3])
3
</pre>
</li>
<li>The elements of a list can be expressions of any type
(including another list) and different elements in the same list
can be of different types, e.g. 'mixed' has three elements; the
first element is a string ("a string"), the second element is an
integer (143), and the third element is another list ([341]).</li>
<li>Lists can contain no elements, in which case they are known as
empty, e.g. 'empty' contains no elements, but is still a list!</li>
<li>Individual elements of a list are indexed according to their
position in the list. The first position has an index of 0, the
second position an index of 1, etc...</li>
<li>We can access a specific element in a list by using a special
operator in an expression following the format
<code>list[index]</code>. This expression evaluates to the element
in the index'th position of the list. e.g. <code>mylist[0]</code>
is 1, <code>mylist[1]</code> is 2, <code>mixed[2]</code> is
[341].</li>
</ul>
<p>Now that we know about lists, we could use a list to represent the
students names, another to represent their fields of study, and a third
to represent their project descriptions. So we might have</p>
<pre class='listing'>
#a small program to record info about students
name = ["Alice", "Bob", "Carl", "Mallory"]
field = ["Astronomy", "Biochemistry", "Cancer Research", "Maths"]
description = [
"The search for black holes",
"Engineering a better yeast for brewing beer",
"Better pain management in palliative care",
"Finding a polynomial time solution for NP-complete problems"
]
</pre>
<h2>Lists in Detail</h2>
<p>We've already learnt a little about about lists, but there are many
more features to <a class="doclink"
href="http://docs.python.org/lib/typesseq.html">lists</a>, and sadly a
few intricacies we need to know about. Firstly let's deal more
explicitly with the operations that can be performed on lists. If both
'a' and 'b' are lists, 'v' is any expression, and 'i', 'j', and 'k' are
integers then</p>
<ul>
<li><code>a + b</code> concatenates two lists. It returns a new list that contains all the elements of list 'a' and then list 'b'.</li>
<li><code>a * i</code> repeats a list. It returns a new list with that has all the elements of 'a' but repeated 'i' times.</li>
<li><code>a[i]</code> retrieves the 'i'th element of
'a'.</li>
<li><code>a[i:j:k]</code> slices the list. It returns a copy of the list 'a'
from its 'i'th element to its (j-1)'th element, taking only every
k'th element. If 'k' is omitted, every element in the range is
taken. If 'i' or 'j' are omitted they default to beginning of list
and end of list respectively.</li>
<li><code>a[:i]</code> yields a slice from the beginning of 'a' to
the (i-1)'th element of 'a'.</li>
<li><code>a[i:]</code> yields a slice from the 'i'th element to the
end of the list.</li>
<li><code>a[:]</code> yields a slice of the entire list. More
importantly it yields a <strong>copy</strong> of the list!</li>
</ul>
<p>Note that theses operators each return newly created lists, and do
not modify the operand lists in any way. For completeness sake, here
are examples ...</p>
<pre class='listing'>
>>> a = [1,2,3]
>>> a+[4,5]
[1, 2, 3, 4, 5]
>>>
>>> [4,5]+a
[4, 5, 1, 2, 3]
</pre>
<pre class='listing'>
>>> a*2
[1, 2, 3, 1, 2, 3]
>>>
>>> [1]*2+2*[2]
[1, 1, 2, 2]
>>>
>>> [[1]*2,[2]*2]
[[1, 1], [2, 2]]
>>>
>>> [1]*2*3
[1, 1, 1, 1, 1, 1]
>>>
</pre>
<pre class='listing'>
>>> a[0]
1
>>> a[1:3]
[2, 3]
>>> a += [4, 5]
>>> a[0:6:2]
[1, 3, 5]
>>> a[:3]
[1, 2, 3]
>>> a[3:]
[4, 5]
>>> a[:]
[1, 2, 3, 4, 5]
>>>
</pre>
<h2>Assignment to elements of a list</h2>
<p>Lists can have their elements changed.
This sounds a little weird, but consider it this way. The value of the
integer 1 cannot change. We can change the value indicated by a
variable <em>i</em> (which might be 1) to something else, but this doesn't
change the value of the integer 1. Lists are different, because the
value reflects a container of multiple other values, and we can remove,
add, or replace those inner values, i.e. list elements. This changes
the value of the list itself. Practically, this means we can assign
values to specific elements of a list.<p>
<pre class='listing'>
>>> a = [1, 2, 3]
>>> a[0]
1
>>> a[0] = 0
>>> a
[0, 2, 3]
>>>
</pre>
<p>Not only can we assign individual elements of a list a new value,
but we can assign whole slices new values. The funky thing is, we can
replace a specified slice of a list with a list of any length,
effectively extending or shrinking the list in the process.<p>
<pre class='listing'>
>>> a = [1, 2, 5]
>>> a[1:2] = [3]
>>> a
[1, 3, 5]
>>> a[1:2] = [2, 3, 4]
>>> a
[1, 2, 3, 4, 5]
>>> a[1:4] = [3]
>>> a
[1, 3, 5]
>>>
</pre>
<h2>Comparing Lists</h2>
<p>The comparison of lists to other lists, and other types is also
slightly different to the comparison of simple types (int, float,
bool). Specifically:</p>
<ul>
<li><code>a == b</code> checks two lists are the same. It returns true if all the elements of 'a' are the same as the elements of 'b'.</li>
<li><code>a < b</code> yields Less Than. Note that lists are
compared in sequence order, meaning that 'a' is less than 'b' if
'a's first element is less than 'b's first element. If 'a's first
element and 'b's first element are equal, the second elements are
checked, etc...</li>
<li><code>v in a</code> is True only if the list a contains an
element whose value is that of the expression 'v'.</li>
<li><code>a is b</code> is True only if 'a' and 'b' are the same
list.</li>
</ul>
<p>Note the final point, namely the 'is' operator. This is one of those
intricacies we mentioned earlier. The contents of a list can be
changed. This is not true of an integer for example. One cannot change
the contents of the integer 1. This introduces a slight complexity. If
'a' is 1 and 'b' is 1 then 'a' and 'b' are the same. But if <code>a =
[1]</code>, and <code>b = [1]</code>, they <strong>are</strong> not the
same. They may be equal, but are not the same list. They are different
lists. Again, examples to the rescue</p>
<pre class='listing'>
>>> a = [1,2]
>>> b = [1,2]
>>> a == b
True
>>> a is b
False
>>>
>>> b[0] = 3
>>> b
[3, 2]
>>> a
[1, 2]
>>>
</pre>
<pre class='listing'>
>>> a = [1,2]
>>> b = a
>>> a == b
True
>>> a is b
True
>>> b[0] = 3
>>> b
[3, 2]
>>> a
[3, 2]
>>>
</pre>
<p>Note how the second line of the second example violates our notion
of assignment, which was: The assignment statement assigns the value of
the expression on the right to the variable on the left. But clearly,
we are not just assigning the value ([1,2]), because later when we
change the first element of 'b' to 3, we also appear to change the
first element of 'a'. Weird. There is a technical explanation for this,
but is really not worth knowing at this point as it is more likely to
confuse than clarify. What this does mean however is that we need to be
aware of the special case of assignment to a single variable of
types that can be changed!</p>
<div class="summary">
When, in an assignment statement <code>a = b</code>, if 'b' is of
<strong>mutable type</strong>(a type that can have its values
changed), the assignment statement
<strong>makes 'a' a synonym of 'b'</strong>, i.e. they become
different names for the same variable.
</div>
<p>Also note how we assigned a value to an element of the list,
changing some of it's contents. Python is quite advanced in terms of
how it can handle assignments involving lists, so let's explore its
features a bit. If 'a' is the list [1, 2, 3], 'b' is some expression of
any value, and 'l' is some expression of type list.</p>
<ul>
<li><code>a[0] = b</code> assigns the value of 'b' to the 0'th
element of 'a'. (The mutable type special case applies)</li>
<li><code>a[0:2] = l</code> removes the slice range specified on
the left and replaces the removed elements with the contents of
'l'. This does <strong>not</strong> make 'a' and 'l' synonyms.</li>
</ul>
<p>If we wish to make a copy of a list that is not a synonym, we assign
to the slice of the full list, e.g. <code>a = b[:]</code> (where 'b' is
a list)</p>
<h2>Lists as Objects</h2>
<p>In addition to the operators that can act on lists, list are
objects. <strong>Object</strong> is a term used in computer science to
refer specifically to something which has both code and data associated
with it directly. Objects will be covered in far greater detail later
on in the course, but in the meanwhile we need to be aware of some
syntactical features they provide.</p>
<p>Objects have code associated with them in functions called
<strong>methods</strong>. Methods are bound to every variable of an
object type individually, meaning if two different variables, 'a' and
'b', are of the same type which is an object type, then 'a' and 'b'
both have the same set of methods but their methods are distinct from
one another. When 'a' calls a method, that method acts only on 'a', and
when 'b' calls that same method, the method will act only on 'b'. Read
it again, it makes sense. In fact examples will prove it's quite
intuitive.</p>
<pre class="listing">
>>> a = [1, 2, 3]
>>> b = ["A", "B", "C"]
>>> a.index(2)
1
>>> b.index(2)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: 2 is not in list
>>> b.index("C")
2
</pre>
<p>Looking at the examples we notice there is some new notation, of the
form <code><list>.<method>()</code>. This 'dot notation'
indicates that we are obtaining a method of the list object (called
index in the case of the example), and our use of brackets indicates we
wish to call it.</p>
<div class="summary">
Methods are simply functions associated with a particular type.
</div>
<p>Note that <code>a.index(2)</code> and <code>b.index(2)</code> return
different results. In fact the 'b.index' case produces an error.
Obviously they are doing different things, despite being given the same
parameter (2). What the index method does is search for a given value
in the elements of <strong>its</strong> list. When called using
'a.index' its list is 'a', when called using 'b.index' its list is 'b'.
Since the value 2 is an element of the list 'a', index returns its
index position (1), meaning it can be found in the second position in
the list. But the value 2 is not an element of the list 'b', hence
index will cause an error.</p>
<p>That being said, let's round off our knowledge of lists by
enumerating the list methods that will be useful to us.</p>
<ul>
<li>
<code><list>.append(<expression>)</code><br />
Appends the value of <expression> to the end of
<list>.
<pre class='listing'>
>>> a = []
>>> a.append('one')
>>> a
['one']
>>>
</pre>
</li>
<li>
<code><list>.count(<expression>)</code><br />
Returns the number of elements in <list> with same value
as that of <expression>.
<pre class='listing'>
>>> a = ['a', 'c', 'g', 't', 't', 'a']
>>> a.count('a')
2
>>>
</pre>
</li>
<li>
<code><list>.index(<expression>)</code><br />
Returns the index of the first element in <list> that has
the same value as <expression>.
<pre class='listing'>
>>> a = ['a', 'c', 'g', 't', 't', 'a']
>>> a.index('t')
3
>>>
</pre>
</li>
<li>
<code><list>.insert(<index expression>, <object
expression>)</code><br /> Inserts the value of <object
expression> <strong>before</strong> the element at the
position indicated by <index expression>.
<pre class='listing'>
>>> a = ['a', 'c', 'g', 't', 't', 'a']
>>> a.insert(2,'newitem')
>>> a
['a', 'c', 'newitem', 'g', 't', 't', 'a']
>>>
</pre>
</li>
<li>
<code><list>.pop()</code><br /> Removes the last element
from the end of the list, and returns it's value.
<pre class='listing'>
>>> a = ['a', 'c', 'g', 't', 't', 'a']
>>> a.pop()
'a'
>>> a
['a', 'c', 'g', 't', 't']
>>>
</pre>
</li>
<li>
<code><list>.remove(<expression>)</code><br />
Removes the first element in <list> that has the same
value as <expression>.
<pre class='listing'>
>>> a = ['a', 'c', 'newitem', 'g', 't', 't', 'a']
>>> a.remove('newitem')
>>> a
['a', 'c', 'g', 't', 't', 'a']
>>>
</pre>
</li>
<li>
<code><list>.reverse()</code><br /> Reverses the order of
elements in <list>.
<pre class='listing'>
>>> a = ['alpha', 'beta', 'gamma', 'delta']
>>> a.reverse()
>>> a
['delta', 'gamma', 'beta', 'alpha']
>>>
</pre>
</li>
<li>
<code><list>.sort()</code><br /> Sorts the elements of
<list>.
<pre class='listing'>
>>> a = ['delta', 'gamma', 'beta', 'alpha']
>>> a.sort()
>>> a
['alpha', 'beta', 'delta', 'gamma']
>>>
</pre>
</li>
</ul>
<!--
<h2>List Comprehensions</h2>
<p>A list comprehension is a special syntactic element of the python
language that allows rapid construction of a new list from the elements
of an old list. They are a syntactic contraction of the pattern:</p>
<pre class='listing'>
new_list = []
for element in old_list:
new_list.append(<something done with element>)
</pre>
<p>List comprehensions have the following basic syntax:</p>
<pre class='definition'>
[<expression of <em>e</em>> for <em>e</em> in <old_list>]
</pre>
<p>The list comprehension is an expression itself which evaluates as a
list containing the results of the expression of <em>e</em> as each
element applied to the <em>e</em>'s of the old list. Example time:</p>
<pre class='listing'>
Python 2.5.2 (r252:60911, Aug 7 2008, 21:06:43)
[GCC 4.1.2 (Gentoo 4.1.2 p1.0.2)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> [e for e in [2, 4, 5]]
[2, 4, 5]
>>> [2*e for e in [2, 4, 5]]
[4, 8, 10]
>>> [e*e for e in [2, 4, 5]]
[4, 16, 25]
>>> [0 for e in [2, 4, 5]]
[0, 0, 0]
>>> dwarfs = [
... 'Happy',
... 'Grumpy',
... 'Sleepy',
... 'Sneezy',
... 'Doc',
... 'Bashful',
... 'Dopey']
>>> [n.startswith('S') for n in dwarfs]
[False, False, True, True, False, False, False]
>>> [n.endswith('y') for n in dwarfs]
[True, True, True, True, False, False, True]
>>> [[i]*3 for i in range(3)]
[[0, 0, 0], [1, 1, 1], [2, 2, 2]]
</pre>
<p>Additionally we can select which elements we want to bring in from
our old list into our new one using a filter clause.<p>
<pre class='definition'>
[<expression of <em>e</em>> for <em>e</em> in <old_list> if <some other expression of <em>e</em>>]
</pre>
<p>Using a filter clause our new list may not have as many elements as
out old list. Let's get only dwarfs names if they start with 'S':</p>
<pre class='listing'>
>>> [n for n in dwarfs if n.startswith('S')]
['Sleepy', 'Sneezy']
</pre>
<p>How cool is this?</p>
-->
<h2>Exercises</h2>
<p>Given the list <code>l = ['There', 'are', 9000000, 'bicycles', 'in', 'Beijing']</code></p>
<ol>
<li>How many elements does the list have? How would one find this
out programatically?</li>
<li>What is the index of the non-string element?</li>
<li>What is the output of <code>print(l[1:4])</code>?</li>
<li>What is the value of <code>[1, 3] + [2, 4]</code>?</li>
<li>What is the value of <code>[1, 3] + [[2, 4]]</code>?</li>
<li>What is the difference between appending a value to a list and
adding the same value within its own list using the concatenation
operator?</li>
<li>What is the slice notation to extract the word 'mickles' from
the <strong>string</strong> 'How many mickles are there in a
muckle?'</li>
<!--
<li>Write a list comprehension that produces a list of 3 lists of
length 3, where each inner list starts with an integer one greater
than the start of the previous list, and the first list starts at
zero.</li>
<li>Write a list comprehension that contains a two element list for
each letter of the alphabet, which contains as its first element,
the letter of the alphabet, and its second element a boolean value
representing whether any of the dwarf names start with that
letter.</li>
<li>Modify your answer to question 6 to contain the number of dwarf
names beginning with each letter, instead of simply True or False.
</li>
-->
<li>Write a program that outputs the position of every 't' in the
list ['a', 'c', 'g', 't', 't', 'a', 't']. Use the index method,
don't do it manually.</li>
<li>Write a program that asks the user to enter a sequence of up to
5 x:y coordinates with both x and y in the range 0 to 4, ending
their sequence entry by providing a blank line for the x
coordinate. Then display a five by five grid of '#' characters,
with the points in the grid entered by the user left blank. Assume
x increases from left to right, and y increases from top to bottom.
Example input/output is given ...
<pre class='listing'>Coordinates range from 0 to 4!
Please enter pair of coordinates (x:y), leave x blank to terminate sequence.
X> 3
Y> 3
Please enter pair of coordinates (x:y), leave x blank to terminate sequence.
X> 4
Y> 1
Please enter pair of coordinates (x:y), leave x blank to terminate sequence.
X> 1
Y> 4
Please enter pair of coordinates (x:y), leave x blank to terminate sequence.
X>
#####
####
#####
### #
# ###
</pre>
</li>
</ol>
<div class="centered">
[<a href="while_loops.html">Prev: Flow Control: Conditional Loops</a>] [<a href="index.html">Course Outline</a>] [<a href="tuples.html">Next: Tuples</a>]
</div>
</div>
<div class="pagefooter">
Copyright © James Dominy 2007-2008; Released under the <a href="http://www.gnu.org/copyleft/fdl.html">GNU Free Documentation License</a><br />
<a href="intropython.tar.gz">Download the tarball</a>
</div>
</body>
</html>