Lists¶

What do we already know about lists?¶

List operations

  • Creation
  • Querying
  • Modification

Loop Examples¶

see in python tutor

In [ ]:
for num in [2, 4, 6]:
    print(num)
In [ ]:
for i in [1, 2, 3]:
    print("Hi there!")
In [5]:
for char in "happy": #sequence is a string, NOT a list
    print(char)      #prints the values of sequence
h
a
p
p
y

The range function¶

A typical for loop does not use an explicit list:

In the following,

for i in range(5):
  … body

range(5) produced the numbers in the sequence [0, 1, 2, 3, 4]

  • note that range(5) is not the same as the list [0, 1 ,2, 3, 4]
  • list(range(5)) is equivalent to the list [0, 1, 2, 3, 4]

Detailed usage (1, 2, or 3 arguments)

  • range(5): cycles through [0, 1, 2, 3, 4] -> Upper limit (exclusive)

  • range(1, 5): cycles through [1, 2, 3, 4] -> Lower limit (inclusive)

  • range(1, 10, 2): cycles through [1, 3, 5, 7, 9] -> step (distance between elements)

What is a list?¶

A list is an ordered sequence of values

A list of integers:

  • [3, 1, 4, 1, 5, 9]

A list of strings:

  • ["Once", "upon", "a", "time", "there"]

Each value has an index

  • for [3, 1, 4, 1, 5, 9]
Index 0 1 2 3 4 5
List Entry 3 1 4 1 5 9

Indexing is zero-based (counting starts with zero):

In [1]:
# Getting length of a list
print(len([3,1,4,1,5,9]))
6
In [2]:
print(len([1, 2, 3]))
3
In [4]:
print(len(["a", 543, 123, "basdf", 19348934876198346]))
5
In [6]:
len([1, 2, 3])
Out[6]:
3
In [7]:
len("happy")
Out[7]:
5
In [8]:
len(["happy"])
Out[8]:
1

List Operations¶

What operations should a list support efficiently and conveniently?

  • Creation
  • Querying
  • Modification

List Creation¶

  • run the following cells from top to bottom
  • see in python tutor
In [9]:
a = [3, 1, 2 * 2, 1, 10 / 2, 10 - 1]
print(a)
[3, 1, 4, 1, 5.0, 9]
In [11]:
y = 5
x = y + 2
x
Out[11]:
7
In [14]:
b = [5, 3.0, 'hi', True]
print(b)
[5, 3.0, 'hi', True]
In [15]:
a
Out[15]:
[3, 1, 4, 1, 5.0, 9]
In [16]:
c = [4, 'a' + 'z', 4 / 2, a]
print(c)
[4, 'az', 2.0, [3, 1, 4, 1, 5.0, 9]]
In [18]:
d = [[1, 2], [3, 4], [5, 6, a], [[[[[[[[[[]]]]]]]]]]]
print(d)
[[1, 2], [3, 4], [5, 6, [3, 1, 4, 1, 5.0, 9]], [[[[[[[[[[]]]]]]]]]]]
In [19]:
a = [1, 2, 3]
b = [-1, 0, a]
In [20]:
b
Out[20]:
[-1, 0, [1, 2, 3]]
In [21]:
2 + 2
Out[21]:
4
In [22]:
'a' + 'z'
Out[22]:
'az'
In [25]:
c = [-1, 0] + [1, 2, 3]
c
Out[25]:
[-1, 0, 1, 2, 3]
In [34]:
a = [1, 2, 3]
a.append(4)
a
Out[34]:
[1, 2, 3, 4]
In [31]:
c
Out[31]:
[-1, 0, 1, 2, 3]
In [35]:
a.append(b)
a
Out[35]:
[1, 2, 3, 4, [-1, 0, [1, 2, 3, 4, 4]]]
In [38]:
a = [1, 2, 3]
b = [4, 5, 6]
In [ ]:
a.append(b)
a
Out[ ]:
[1, 2, 3, [4, 5, 6]]
In [39]:
a.extend(b)
a
Out[39]:
[1, 2, 3, 4, 5, 6]
In [40]:
x = 2
x
Out[40]:
2
In [41]:
a = [1, 2, 3]
a
Out[41]:
[1, 2, 3]
In [42]:
a[0]
Out[42]:
1
In [43]:
a[1]
Out[43]:
2
In [44]:
a[-1]
Out[44]:
3
In [45]:
a[-2]
Out[45]:
2
In [51]:
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10][0:5:2]
Out[51]:
[1, 3, 5]
In [49]:
list(range(0, 5))
Out[49]:
[0, 1, 2, 3, 4]
In [53]:
a = [3, 1, 4, 1, 5, 9]
a[1:3]
Out[53]:
[1, 4]
In [54]:
a = [2, 7, 3, 9, 4]
In [56]:
a[3]
Out[56]:
9
In [57]:
a[5]
---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
Cell In[57], line 1
----> 1 a[5]

IndexError: list index out of range
In [ ]:
print(a[3], a[5], a[1])
---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
Cell In[55], line 1
----> 1 print(a[3], a[5], a[1])

IndexError: list index out of range
In [59]:
-0
Out[59]:
0
In [58]:
print(a[3], a[-1], a[1])
9 4 7

List Querying¶

Expressions that return parts of lists:

Single element: mylist[index]

  • The single element stored at that location
In [ ]:
l = [3,1,4,1,5,9]
print(l[2])
In [ ]:
 

Sublist (“slicing”): mylist[start:end]

  • the sublist that starts at start

  • index start and ends at index end – 1

  • If start is omitted: defaults to 0

  • If end is omitted: defaults to len(mylist)

  • mylist[:] and mylist[0:len(mylist)] both evaluate to the whole list

In [ ]:
a = [0, 1, 2, 3, 4]
print(a[0])
In [ ]:
a = [0, 1, 2, 3, 4]
print(a[5])
In [ ]:
a = [0, 1, 2, 3, 4]
print(a[6])
In [ ]:
a = [0, 1, 2, 3, 4]
print(a[-1]) # last element in list
In [ ]:
a = [0, 1, 2, 3, 4]
print(a[-2]) # next to last element
In [ ]:
a = [0, 1, 2, 3, 4]
print(a[0:2])
In [ ]:
a = [0, 1, 2, 3, 4]
print(a[0:-1])
In [1]:
my_list = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5, 8, 9]
9 in my_list
Out[1]:
True
In [2]:
my_list.index(9)
Out[2]:
5
In [3]:
my_list.index(7)
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Cell In[3], line 1
----> 1 my_list.index(7)

ValueError: 7 is not in list
In [4]:
if 7 in my_list:
    my_list.index(7)
In [5]:
my_list.count(7)
Out[5]:
0
In [6]:
if my_list.count(7) != 0:
    my_list.index(7)
In [7]:
my_list.count(9)
Out[7]:
2

List Modification¶

  • Insertion
  • Removal
  • Replacement
  • Rearrangement

List insertions¶

mylist.append(x)

  • Extend mylist by inserting x at the end

mylist.extend(L)

  • Extend mylist by appending all the items in the argument list L to the end of mylist

ylist.insert(i, x)

  • Insert item x before position i.

a.insert(0, x)

  • inserts at the front of the list

a.insert(len(a), x)

  • is equivalent to a.append(x)
In [ ]:
lst = [1, 2, 3, 4]
lst.append(5)
print(lst)
In [ ]:
lst = [1, 2, 3, 4]
lst.extend([6, 7, 8])
print(lst)
In [26]:
lst = [1, 2, 3, 4]
In [9]:
lst[3]
Out[9]:
4
In [16]:
lst[3.5]
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In[16], line 1
----> 1 lst[3.5]

TypeError: list indices must be integers or slices, not float
In [17]:
lst[True]
Out[17]:
2
In [ ]:
3 + True
Out[ ]:
4
In [ ]:
lst['h' in 'hello']  # DO NOT DO THIS: THIS IS BAD CODE
Out[ ]:
2
In [12]:
lst[int(3.0)]
Out[12]:
4
In [20]:
# lst.insert(<index of new item>, <new item>)
In [13]:
lst.insert(3, 3.5)
In [14]:
lst
Out[14]:
[1, 2, 3, 3.5, 4]
In [15]:
lst[3]
Out[15]:
3.5
In [21]:
len(lst)
Out[21]:
5
In [27]:
lst.insert(8, "hello")
In [28]:
lst
Out[28]:
[1, 2, 3, 4, 'hello']

Comprehension check

Which of the following is printed by the code below

  • A) 4
  • B) 5
  • C) 2
  • D) [4, 6]
  • E) IndexError: list index out of range
lst = [1, 3, 5]
lst.insert(2, [4, 6])
print(lst[2])
In [ ]:
lst = [1, 3, 5]
lst.insert(2, [4, 6])
print(lst[2])

List removal¶

mylist.remove(x)

  • Remove the first item from the list whose value is x
  • It is an error if there is no such item
  • Returns None

mylist.pop([i])

  • Remove the item at the given position in the list, and return it.
  • If no index is given, mylist.pop() removes and returns the last item in the list.
  • Notation from the Python Library Reference: The square brackets around the parameter, “[i]”, means the argument is optional. It does not mean you should type square brackets at that position.
In [ ]:
#Examples
lst = [1, 2, 3, 4, 5, 6, 7]
print(lst.pop())
In [ ]:
lst = [1, 2, 3, 4, 5, 6, 7]
print(lst.pop(1))
In [ ]:
lst = [1, 2, 3, 4, 5, 6, 7]
print(lst.remove(3))
In [ ]:
lst = [1, 2, 3, 4, 5, 6, 7]
lst.remove(3)
print(lst)

List replacement¶

mylist[index] = new_value
mylist[start:end] = new_sublist

Replaces mylist[start] to mylist[end – 1] with new_sublist

Can change the length of the list

Examples:

mylist[start:end] = []

removes mylist[start]… mylist[end – 1]

mylist[len(mylist):] = L

is equivalent to a.extend(L)

In [ ]:
#Examples
lst = [1, 2, 3, 4, 5, 6, 7]
lst[3] = 'blue'
print(lst)
In [ ]:
lst = [1, 2, 3, 4, 5, 6, 7]
lst[1:3] = [10, 11, 12]
print(lst)

List Rearrangement¶

mylist.sort()

  • Sort the items of the list, in place.
  • “in place” means by modifying the original list, not by creating a new list.

mylist.reverse()

  • Reverse the elements of the list, in place.

both sort() and reverse() return none

In [ ]:
#Example
lst = [1, 2, 3, 4, 5, 6, 7]
lst.reverse()
print(lst)
lst.sort()
print(lst)

List modification examples¶

  • see in python tutor
In [ ]:
lst = [10, 12, 23, 54, 15]
lst.append(7)
lst.extend([8, 9, 3])
lst.insert(2, 2.75)
lst.remove(3)
print(lst.pop())
print(lst.pop(4))
lst[1:5] = [20, 21, 22]
lst2 = [4, 6, 8, 2, 0]
lst2.sort()
lst2.reverse()
lst3 = lst2
lst4 = lst2[:]
lst2[-1]= 17

print(lst)
print(lst2)
print(lst3)
print(lst4)

List operations comprehension check¶

  1. What will convert list a into [1, 2, 3, 4, 5]

a = [1, 3, 5]

  • A. a.insert(1, 2)

    a.insert(2, 4)

  • B. a[1:2] = [2, 3, 4]

  • C. a.extend([2, 4])

  • D. a[1] = 2

    a[3] = 4

Excercise: List lookup¶

Goal: implement the following (see in python tutor)

def my_index(lst, value):
  """Return the position of the first occurrence
  of value in the list lst. Return None if value
  does not appear in lst."""

Examples:

story = ["Once", "upon", "a", "time", "there", "was", "a"]

my_index(story, "a") → 2

my_index(story, "there") → 4

Note : my_list[my_index(my_list, x)] == x

Solution 1 (see in python tutor)¶

In [ ]:
def my_index(lst, value):
  """Return the position of the first
  occurrence of value in the list lst.
  Return None if value does not appear
  in lst."""
  i = 0
  for element in lst:
    if element == value:
      return i
    i = i + 1
  return None

story = ["Once", "upon", "a", "time", "there", "was", "a"]
print(my_index(story, "a"))
print(my_index(story, "there"))

Solution 2 (see in python tutor)¶

In [ ]:
def my_index(lst, value):
  """Return the position of the first
  occurrence of value in the list lst.
  Return None if value does not appear
  in lst."""
  for i in range(len(lst)):
    if lst[i] == value:
      return i
  return None

story = ["Once", "upon", "a", "time", "there", "was", "a"]
print(my_index(story, "there"))
print(my_index(story, "a"))

Exercise: Convert Units¶

(see in python tutor)

Using the following:

def cent_to_fahr(cent):
  return cent / 5.0 * 9 + 32

ctemps = [-40, 0, 20, 37, 100]

ftemps = []

Without setting it directly, set ftemps to [-40, 32, 68, 98.6, 212]

Answer (see in python tutor)

In [ ]:
def cent_to_fahr(cent):
  return cent / 5.0 * 9 + 32

ctemps = [-40, 0, 20, 37, 100]

ftemps = []
for c in ctemps:
    f = cent_to_fahr(c)
    ftemps.append(f)

print(ftemps)

More on list slicing¶

mylist[startindex:endindex] evaluates to a sublist of the original list

  • mylist[index] evaluates to an element of the original list

  • Arguments are like those to the range function mylist[start:end:step]

    • start index is inclusive, end index is exclusive
    • All 3 indices are optional
    • Can assign to a slice: mylist[s:e] = yourlist

Example (see in python tutor):

In [ ]:
test_list = ['e0', 'e1', 'e2', 'e3', 'e4', 'e5', 'e6']
my_list = test_list[2:]
print(my_list)
In [ ]:
test_list = ['e0', 'e1', 'e2', 'e3', 'e4', 'e5', 'e6']
my_list = test_list[:5]
print(my_list)
In [ ]:
test_list = ['e0', 'e1', 'e2', 'e3', 'e4', 'e5', 'e6']
my_list = test_list[-1]
print(my_list)
In [ ]:
test_list = ['e0', 'e1', 'e2', 'e3', 'e4', 'e5', 'e6']
my_list = test_list[-4:]
print(my_list)
In [ ]:
test_list = ['e0', 'e1', 'e2', 'e3', 'e4', 'e5', 'e6']
my_list = test_list[:-3]
print(my_list)
In [ ]:
test_list = ['e0', 'e1', 'e2', 'e3', 'e4', 'e5', 'e6']
my_list = test_list[:]
print(my_list)
In [ ]:
test_list = ['e0', 'e1', 'e2', 'e3', 'e4', 'e5', 'e6']
my_list = test_list[::-1]
print(my_list)

Answer

test_list[2:] From e2 to the end of the list

test_list[:5] From beginning up to (but not including) e5

test_list[-1] Last element

test_list[-4:] Last four elements

test_list[:-3] Everything except last three elements

test_list[:] Get a copy of the whole list

test_list[::-1] Reverse the list

How to evaluate a list expression¶

There are two new forms of expression:

  • List creation (aka, list literals): [1, 2, 3, 4]
  • List indexing (aka, dereferencing): a[i]

Note: In the previous examples, there are the same tokens “[]” with two distinct meanings

Evaluating list expressions¶

[a, b, c, d] list creation

  • To evaluate:
    • evaluate each element to a value, from left to right
    • make a list of the values -The elements can be arbitrary values, including lists:
    • ["a", 3, fahr_to_cent(-40), [3 + 4, 5 * 6]]

a[b] list indexing

a is the list expression, b is the index

  • To evaluate:
    • evaluate the list expression to a value
    • evaluate the index expression to a value
    • if the list value is not a list, execution terminates with an error
    • if the element is not in range (not a valid index), execution terminates with an error
    • the value is the given element of the list value (counting from zero)

List expression examples¶

What does this mean (or is it an error)? (see in python tutor)

In [ ]:
["Once", "upon", "a", "time", "there"][2]
In [ ]:
["Once", "upon", "a", "time", "there"][0,2,3]
In [ ]:
["Once", "upon", "a", "time", "there"][[0,2,3]]
In [ ]:
["Once", "upon", "a", "time", "there"][[0,2,3][1]]

Two dimensional nested lists¶

Each single element within mylist is also a list.

(Remember: a list can contain just about anything.)

In [ ]:
mylist = [
  [1, 2, 3],
  [4, 5, 6],
  [7, 8, 9]
]

mylist[0] evaluates to a list

In [ ]:
mylist = [
  [1, 2, 3],
  [4, 5, 6],
  [7, 8, 9]
]
mylist[0]

mylist[0] is an expression that evaluates to the first item in mylist. This just happens to also be another list expression

mylist[0][0] evaluates to the first element of the first list in the nested list

In [ ]:
mylist = [
  [1, 2, 3],
  [4, 5, 6],
  [7, 8, 9]
]
mylist[0][0]

Note the double square brackets below. Adding a list within a list within a list.

Add blockquote

In [ ]:
mylist = [
  [1, 2, 3],
  [4, 5, 6],
  [7, 8, 9]
]
mylist.append([[10,11,12]])
print(mylist)

Recall that items within a list don't have to all be the same type. What will the following do?

In [ ]:
mylist[0][0][0]