The List Data Type

List & Index

A list is a value that contains multiple values. The values in a list are also called items.

In [1]:
spam = ['cat', 'bat', 'rat', 'elephant']
spam
Out[1]:
['cat', 'bat', 'rat', 'elephant']

A list can hold multiple data types and you don't need to define how long the list will be beforehand (dynamic array)

In [2]:
spam = ['hi', 1, 2, 3]
spam
Out[2]:
['hi', 1, 2, 3]

You can access items in a list with it's integer index which starts at 0, not 1

In [3]:
spam[0]
Out[3]:
'hi'

List of List/ Nested List

In [4]:
spam = [['cat', 'bat'], [10, 20, 30]]
spam[0]
Out[4]:
['cat', 'bat']
In [5]:
spam[1][1]
Out[5]:
20

Negative indexes

You can also use negative indexes. -1 refers to the last item. -2 refers to the second to last item, and so on

In [6]:
spam = ['cat', 'bat', 'rat', 'elephant']
spam[-1] # 'elephant'
spam[-2] # 'rat'
'The ' + spam[-1] + ' is fat'
Out[6]:
'The elephant is fat'

Slice

You can get multiple items from the list using a slice. The slice has two indexes. The new list's items start at the first index and go up to, but does not include, the second index

In [7]:
spam = ['cat', 'bat', 'rat', 'elephant']
spam[1:3]
Out[7]:
['bat', 'rat']

Slice Shortcuts

In [8]:
spam = ['cat', 'bat', 'rat', 'elephant']
spam[:2]
Out[8]:
['cat', 'bat']
In [9]:
spam[1:]
Out[9]:
['bat', 'rat', 'elephant']

Changing a List's Items

In [10]:
spam = [10, 20, 30]
spam[1] = 'Hello'
spam
Out[10]:
[10, 'Hello', 30]
In [11]:
spam[1:3] = ['CAT', 'DOG', 'MOUSE']
spam
Out[11]:
[10, 'CAT', 'DOG', 'MOUSE']

del Statements

You can remove an item from a list by using del. Think of del as an un-assignment statement

In [12]:
spam = ['cat', 'bat', 'rat', 'elephant']
del spam[2]
spam
Out[12]:
['cat', 'bat', 'elephant']
In [13]:
del spam[2]
spam
Out[13]:
['cat', 'bat']

String and List Similarities

The len() function, concatenation, and replication work the same way with lists that they do with strings

String List
Length len('Hello') # 5 len([1, 2, 3]) # 3
Concatenation 'Hello'+' World' # 'Hello World' [1, 2] + [5, 6] # [1, 2, 5, 6]
Replication 'Hello' * 2 # 'HelloHello' [1, 2] * 2 # [1, 2, 1, 2]

The list() Function

You can convert a value into a list by passing it to the list() function

In [14]:
list('Hello')
Out[14]:
['H', 'e', 'l', 'l', 'o']

The in and not in Operators

In [15]:
'howdy' in ['hello', 'hi', 'howdy', 'heyas']
Out[15]:
True
In [16]:
42 in ['hello', 'hi', 'howdy', 'heyas']
Out[16]:
False
In [17]:
'howdy' not in ['hello', 'hi', 'howdy', 'heyas']
Out[17]:
False

For Loops with Lists, Multiple Assignment, Augmented Assignment Operators

List-Like Values

The range() function returns a list-like value

In [18]:
range(4)
Out[18]:
range(0, 4)

The range() function can be passed to the list() function if you need an actual list value

In [19]:
list(range(4))
Out[19]:
[0, 1, 2, 3]
In [20]:
list(range(2, 10, 2))
Out[20]:
[2, 4, 6, 8]

For loop with List

For loops technically iterate over the values in a list

In [21]:
for i in range(4):
  print(i)
0
1
2
3

which is the same as:

In [22]:
for i in [0, 1, 2, 3]:
  print(i)
0
1
2
3
In [23]:
supplies = ['pens', 'staplers', 'flame-throwers', 'binders']

for i in range(len(supplies)):
  print('Index ' + str(i) + ':' + supplies[i])
Index 0:pens
Index 1:staplers
Index 2:flame-throwers
Index 3:binders

Multiple Assignment

Variables can swap their values using multiple assignments

In [24]:
cat = ['fat', 'orange', 'loud']
size, color, disposition = cat
In [25]:
size
Out[25]:
'fat'
In [26]:
color
Out[26]:
'orange'
In [27]:
disposition
Out[27]:
'loud'
In [28]:
size, color, disposition = 'skinny', 'black', 'quiet'
In [29]:
size
Out[29]:
'skinny'
In [30]:
color
Out[30]:
'black'
In [31]:
disposition
Out[31]:
'quiet'

Swapping variables

In [32]:
a = 'AAA'
b = 'BBB'
a, b = b, a
In [33]:
a
Out[33]:
'BBB'
In [34]:
b
Out[34]:
'AAA'

Augmented Assignment Operators

Augmented Assignment Operators like += are used as shortcuts

Augmented assignment statement Equivalent assignment statement
spam += 1 spam = spam + 1
spam -= 1 spam = spam - 1
spam *= 1 spam = spam * 1
spam /= 1 spam = spam / 1
spam %= 1 spam = spam % 1
In [35]:
spam = 42
spam = spam + 1
spam += 1
spam
Out[35]:
44

List Methods

Methods are functions that are "called on" values. The following list methods operate on the list "in place", rather than returning a new list value.

The index() List Method

The index() list method returns the index of an item in the list

In [36]:
spam = ['hello', 'hi', 'howdy', 'heyas']
spam.index('hello')
Out[36]:
0
In [37]:
# spam.index('bla') #ValueError

Duplicate values in list

In [38]:
spam = ['Sophie', 'Pooka', 'Fat-tail', 'Pooka']
spam.index('Pooka')
Out[38]:
1

The append() and insert() List Methods

The append() list method adds a value to the end of a list. The insert() method adds a value anywhere inside a list. Both methods returns None value.

In [39]:
spam = ['cat', 'dog', 'bat']
spam.append('mouse')
spam
Out[39]:
['cat', 'dog', 'bat', 'mouse']
In [40]:
spam = ['cat', 'dog', 'bat']
spam.insert(1, 'chicken')
spam
Out[40]:
['cat', 'chicken', 'dog', 'bat']

The remove() List Method

The remove() list method removes an item, specified by a value, from a list (compare to del statement which specify the index)

In [41]:
spam = ['cat', 'bat', 'rat', 'elephant']
spam.remove('bat')
spam
Out[41]:
['cat', 'rat', 'elephant']
In [42]:
# spam.remove('blah') # ValueError
In [43]:
del spam[0]
spam
Out[43]:
['rat', 'elephant']

The remove() list method can only remove 1 item from the list

In [44]:
spam = ['cat', 'bat', 'rat', 'cat']
spam.remove('cat')
spam
Out[44]:
['bat', 'rat', 'cat']

The pop() List Method

The pop() list method will remove an item in the list. The default is the last item but you can also specify the index of item to be removed

In [45]:
myList = [1,2,3,4]
myList.pop()
Out[45]:
4
In [46]:
myList = [1,2,3,4]
myList.pop(0)
Out[46]:
1

The sort() List Method

The sort() list method sorts the items in a list

In [47]:
spam = [2, 5, 3.14, 1, -7]
spam.sort()
spam
Out[47]:
[-7, 1, 2, 3.14, 5]
In [48]:
spam = ['dogs', 'cats', 'ants']
spam.sort()
spam
Out[48]:
['ants', 'cats', 'dogs']

The sort() method's reverse=True keyword argument can sort in reverse order

In [49]:
spam = ['dogs', 'cats', 'ants']
spam.sort(reverse = True)
spam
Out[49]:
['dogs', 'cats', 'ants']
In [50]:
spam = [1, 'Alice', 33]
# spam.sort() # TypeError

By default, sort() happens in ASCII-betical i.e. uppercase characters come before lowercase characters.

In [51]:
spam = ['Alice', 'carol', 'ants', 'Bob']
spam.sort()
spam
Out[51]:
['Alice', 'Bob', 'ants', 'carol']

To sort in true alphabetical order, pass key=str.lower

In [52]:
spam = ['a', 'Z', 'A', 'z']
spam.sort(key = str.lower)
spam
Out[52]:
['a', 'A', 'Z', 'z']

The sum() List Method

Use the sum() list method to sum up list of numbers

In [53]:
spam = [2,3,4]
sum(spam)
Out[53]:
9

Similarities Between Lists and Strings

Strings can do a lot of things like lists can do, but strings are immutable.

In [54]:
list("Hello")
Out[54]:
['H', 'e', 'l', 'l', 'o']
In [55]:
name = 'Zophie'
name[0]
Out[55]:
'Z'
In [56]:
name[1:3]
Out[56]:
'op'
In [57]:
name[-2]
Out[57]:
'i'
In [58]:
'Zo' in name
Out[58]:
True
In [59]:
'xxx' in name
Out[59]:
False
In [60]:
for letter in name:
  print(letter)
Z
o
p
h
i
e

Mutable and Immutable Data Types

Immutable values can't be modified "in place" e.g. strings, tuples. You can't actually change an item once it's in there

In [61]:
name = 'Zophie the cat'
name[7]
Out[61]:
't'
In [62]:
# name[7] = 'X' # TypeError

You modify strings by creating New Strings from Slice

In [63]:
name = 'Zophie a cat'
newName = name[0:7] + 'the' + name[8:12]
newName
Out[63]:
'Zophie the cat'

Mutable values can be modified "in place" e.g. lists. You can modify an item in a list

In [64]:
myList = [1,2,3]
myList[0] = 'New'
myList
Out[64]:
['New', 2, 3]

References

The difference between immutable and mutable comes up with "references".

Immutable Example: Integers

In [65]:
spam = 42
cheese = spam
spam = 100
spam
Out[65]:
100
In [66]:
cheese
Out[66]:
42

Mutable Example: Lists

Variables don't contain lists, they contain reference to lists.

In [67]:
spam = [0, 1, 2, 3, 4, 5]
cheese = spam
cheese[1] = 'Hello'
cheese
Out[67]:
[0, 'Hello', 2, 3, 4, 5]
In [68]:
spam
Out[68]:
[0, 'Hello', 2, 3, 4, 5]

spam = [0, 1, 2, 3, 4, 5] stores the reference to the list, not the actual list img

cheese = spam copies the reference, not the list img

cheese[1] = 'Hello' modifies the list that both variables refer to img

Immutable values such as strings don't have this problem because they can't be modified "in place". They can only be replaced by new values.

Video: Facts and Myths About Python Names and Values

References are explained very well in Ned Batchelder's talk, "Facts and myths about Python names and values" (25 minutes)

Passing Lists in Function Calls

When passing a list argument to a function, you are actually passing a list reference, NOT a copy of a list. Change made in a list in a function will affect the list outside the function.

In [69]:
def eggs(cheese):
  cheese.append('Hello')

spam = [1, 2, 3]
eggs(spam)

print(spam)
[1, 2, 3, 'Hello']

The copy.deepcopy() Function

In [70]:
import copy
spam = ['A', 'B', 'C', 'D']
cheese = copy.deepcopy(spam)
cheese[1] = 42

cheese
Out[70]:
['A', 42, 'C', 'D']
In [71]:
spam
Out[71]:
['A', 'B', 'C', 'D']

Line Continuation

The \ line continuation character can be used to strech Python instructions across multiple lines. This is the exception to the rule about block and indentation.

In [72]:
spam = ['apples',
        'oranges',
        'bananas']
spam
Out[72]:
['apples', 'oranges', 'bananas']
In [73]:
print('Four score and seven' + \
      ' years ago...')
Four score and seven years ago...

List Comprehension

In [74]:
x = [1,2,3,4]
out = []
for num in x:
    out.append(num**2)

out
Out[74]:
[1, 4, 9, 16]

which is the same as:

In [75]:
x = [1,2,3,4]
out1 = [num**2 for num in x]

out1
Out[75]:
[1, 4, 9, 16]