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.
numbers = [1, 2, 3, 4] print numbers cheeses = ['swiss', 'cheddar', 'ricotta', 'gouda'] print cheeses
mixed = [1, 'a', 3.45] print mixed
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]
Improve upon that snippet above, to print only the lines a hash ("#") (you might like to use
Hints: list is "iterable" so recall how we loop conveniently through an iterable with a for loop
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
With what other basic type * operator resulted in a very similar behavior?
Why do you think indexing in generic programming languages (C, C++, ...) as a rule starts with 0?
cheeses = 'Feta' print cheeses
Are strings mutable?
All slicing parameters are optional:
l = range(1, 6) print(l)
l[start:stop]contains the elements with indices
start <= i < stop(
stop-1), i.e. includes
startbut does not includes
stride can be negative. Explore on the above example effects -- what does having negative
stride result in?
stop can also be negative. Explore on the above example effects -- what does having negative
stop result in?
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
roster[2:2] = ['Dana', 'Ryan'] print roster
roster[3:5] =  print roster
del roster[2:3] print roster
roster.insert(2, 'Jakob') print roster
appendmethod adds individual items to a list:
roster.append('Tonya') print roster
extendmethod adds a list to the end of an existing list:
adds = ['Ian', 'Stacie'] roster.extend(adds) print roster
roster += ['Anya'] print roster
a = [1, 2, 3] b = [4, 5, 6] c = a + b print a, b, c
a = [1, 2, 3, 4] b = a c = a[:] a = 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
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
empty =  for x in empty: print(x)
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.
nested = [[1, 2, 3], [4, 5, 6], [7, 8, 9]] print nested print nested print nested
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
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
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)
l = [s for s in "something creative"] print(l)
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"]
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