Objectives:
Upon completion of this lesson, you should be able to:
Describe the characteristics of the list in Python
Perform basic operations with lists including creation, concatenation, repetition, slicing, and traversing
There are Four basic containers in Python: list, tuple, set and dictionary. We will first consider possibly the "simplest" one -- list.
In Python, a list is a mutable sequence of values. Mutable means that we can change separate entries within a list
Each value in the list is an element or item
Elements can be any Python data type
Lists can mix data types
Elements can be nested lists
Lists are created with comma-separated values inside brackets.
numbers = [1, 2, 3, 4]
print numbers
cheeses = ['swiss', 'cheddar',
'ricotta', 'gouda']
print cheeses
You can mix types
mixed = [1, 'a', 3.45]
print mixed
and lists with single items (or no items) are lists
single = ['z']
print single, type(single)
empty = []
print empty
print list("I am a string")
and more often you will see the use of str.split()
method to create list of separate "words":
print "I am a string".split()
In Python it is very easy to read external files. Even though we haven't covered that yet, here is a little taster, which reads first 10 lines from a file in the parent directory:
with open("../README.md") as f:
print f.readlines()[:10]
Excercise
Improve upon that snippet above, to print only the lines a hash ("#") (you might like to use str.startwith()
, str.lstrip()
, str.rstrip()
functions)
Hints: list is "iterable" so recall how we loop conveniently through an iterable with a for loop
Extra credit
Enhance to print only the lines which come from the "Code of conduct" sub-section
meat = ['spam']*4
print meat
print [1, 2, 3]*3
Microquiz
With what other basic type * operator resulted in a very similar behavior?
print cheeses[0]
Microquiz
Why do you think indexing in generic programming languages (C, C++, ...) as a rule starts with 0?
Lists are mutable
cheeses[0] = 'Feta'
print cheeses
Microquiz/Excercise
Are strings mutable?
Like strings and other sequences, lists can be sliced.
Slicing syntax:
l[start:stop:stride]
All slicing parameters are optional:
l = range(1, 6)
print(l)
print(l[3:])
l[:3]
l[::2]
Note that
l[start:stop]
contains the elements with indices i
such as start <= i < stop
(i
ranging from start
to stop-1
), i.e. includes start
but does not includes stop
Thererore, l[start:stop]
has (stop-start)
elements.
Excercise #1
stride
can be negative. Explore on the above example effects -- what does having negative stride
result in?
Excercise #2
stop
can also be negative. Explore on the above example effects -- what does having negative stop
result in?
You can use slices to modify the contents of a list:
roster = ['Meghan', 'Tricia', 'Juan',
'Alton', 'Darrel', 'Jen']
print roster
roster[1:3] = ['Sam', 'Kerri'] # Assign multiple entries at once
print roster
roster[3:5] = ['Tayla'] # Assigning less than selected results in "shrinking" of the list
print roster
Slice notation
roster[2:2] = ['Dana', 'Ryan']
print roster
Setting a slice to empty list will delete those elements:
roster[3:5] = []
print roster
Or you can use the del keyword:
del roster[2:3]
print roster
Lists have an insert
method:
roster.insert?
Let's see it in action:
roster.insert(2, 'Jakob')
print roster
The append
method adds individual items to a list:
roster.append('Tonya')
print roster
The extend
method adds a list to the end of an existing list:
adds = ['Ian', 'Stacie']
roster.extend(adds)
print roster
Microquiz
Can also use += operator
roster += ['Anya']
print roster
Or simply the + operator
a = [1, 2, 3]
b = [4, 5, 6]
c = a + b
print a, b, c
The + operator returns a new list that is a concatenation of two lists
The slice operator returns a copy of a list
a = [1, 2, 3, 4]
b = a
c = a[:]
a[2] = 9
print a, b, c
for index in range(len(roster)):
print roster[index]
for student in roster:
print student
for index, student in enumerate(roster):
print index, student
Note how enumerate
keeps track of the index and the item, which can come in handy -- you don't really need to use for i in range(len(l))
to traverse the list
Microquiz
empty = []
for x in empty:
print(x)
Excercise
I have mentioned above zip function which I promised would help to make the world a better place. So -- use learnt knowedge to figure out what it does and come up with a usecase/example for its usage.
You can nest lists of lists of lists...
nested = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
print nested
print nested[0]
print nested[0][1]
Each nested list can be traversed in the same way as an individual list:
By index (less efficient, often ugly):
for i in range(len(nested)):
for j in range(len(nested[i])):
print nested[i][j]
for nest in nested:
for item in nest:
print item
def cumulate(seq):
c_sum = 0
for item in seq:
c_sum += item
return c_sum
a = [12, 78, 32, 82]
s = cumulate(a)
print s
You can return lists from functions:
def only_upper(t):
res = []
for s in t:
if s.isupper():
res.append(s)
return res
text = 'Bold cOlOrs Make for Easy Reading'
secret = only_upper(text)
print secret
In Python, arguments are passed by reference
The parameter in the function is an alias for the argument that was passed in
If a mutable object is changed inside the function, it is also changed outside the function!
Here we illustrate modifying a list in a function:
def change(seq):
print 'Passed in: ' + str(seq)
seq.append('new item')
print 'Changed to: ' + str(seq)
original = [1, 2, 3]
print original
change(original)
print original
def change(seq):
print 'Passed in: ' + str(seq)
seq.append('new item')
print 'Changed to: ' + str(seq)
new_seq = ['created', 'in', 'function']
print 'New seq: ' + str(new_seq)
original = [1, 2, 3]
new_seq = ['outside','the','function']
print original
change(original)
print original
print new_seq
def change(seq=[]):
seq.append(1)
return seq
original = [1, 2, 3]
for i in range(4):
print change()
Instead define default to None and assign within the function, thus a new list would be created on each call:
def change(seq=None):
seq = seq or []
seq.append(1)
return seq
original = [1, 2, 3]
for i in range(4):
print change()
Very powerful technique allowing for efficient construction of new lists.
It is usually prefered over looping regularly to fill up pre-created list. Compare:
l = []
for s in "something creative":
l.append(s)
to
l = [s for s in "something creative"]
print(l)
Miniquiz
well -- above example is boring, since we could accomplish the same by ...?
We could store multiple values per each item right away:
l = [(i, s, len(s)) for i, s in enumerate("something creative")]
print(l)
print [s for s in "something creative" if s in "eai"]
Excercise
Recall the example above for reading section headings from README.md. Create a list comprehension which would create a list of line headings.
[x for x in "123"]
print x
and they would override values defined locally before:
i = "precious"
print i
[i for i in ["evil"]]
print i