Lists 1 - Introduction

Download exercises zip

Browse files online

A Python list is a mutable sequence of heterogeneous elements, in which we can put the objects we want. The order in which we put them is preserved.

What to do

  1. Unzip exercises zip in a folder, you should obtain something like this:

lists
    lists1.ipynb
    lists1-sol.ipynb
    lists2.ipynb
    lists2-sol.ipynb
    lists3.ipynb
    lists3-sol.ipynb
    lists4.ipynb
    lists4-sol.ipynb
    jupman.py

WARNING: to correctly visualize the notebook, it MUST be in an unzipped folder !

  1. open Jupyter Notebook from that folder. Two things should open, first a console and then a browser. The browser should show a file list: navigate the list and open the notebook lists1.ipynb

  2. Go on reading the exercises file, sometimes you will find paragraphs marked Exercises which will ask to write Python commands in the following cells. Exercises are graded by difficulty, from one star ✪ to four ✪✪✪✪

Shortcut keys:

  • to execute Python code inside a Jupyter cell, press Control + Enter

  • to execute Python code inside a Jupyter cell AND select next cell, press Shift + Enter

  • to execute Python code inside a Jupyter cell AND a create a new cell aftwerwards, press Alt + Enter

  • If the notebooks look stuck, try to select Kernel -> Restart

Creating lists

We can create a list by specifying the elements it contains between square brackets, separating them with a comma.

For example, in this list we insert the numbers 7, 4 e 9:

[2]:
[7,4,9]
[2]:
[7, 4, 9]

Like all Python objects, we can associate them to a variable, in this case we create a new one we call my_list:

[3]:
my_list = [7,4,9]
[4]:
my_list
[4]:
[7, 4, 9]

Let’s see what happens in memory, and compare strings representation with lists representation:

[5]:
# WARNING: before using the function jupman.pytut() which follows,
#          it is necessary to first execute this cell with Shift+Enter
#          it's sufficient to execute it only once


import jupman
[6]:
my_string = "prova"

my_list = [7,4,9]

jupman.pytut()
[6]:

We suddenly note a relevant difference. The string remained in the azure region where associations among variables and values usually stay. From variable my_list we see instead an arrow departing to a new yellow memory region, which is created as soon the execution reaches the row where the list is defined.

Later we will analyze more in detail the consequences of this.

In a list the same elements may appear many times:

[7]:
numbers = [1,2,3,1,3]
[8]:
numbers
[8]:
[1, 2, 3, 1, 3]

We can put any element, for example strings:

[9]:
fruits = ["apple", "pear", "peach", "strawberry", "cherry"]
[10]:
fruits
[10]:
['apple', 'pear', 'peach', 'strawberry', 'cherry']

We can also mix the object types contained in a list, for example we can have integers and strings:

[11]:
mix = ["table", 4 ,"chair", 8, 5, 1, "chair"]

In Python Tutor it will be shown like this:

[12]:
mix = ["table", 5 , 4, "chair", 8, "chair"]

jupman.pytut()
[12]:

For convenience we can also write the list on many rows (the spaces in this case do not count, only remember to terminate rows with commas ,)

[13]:
mix = ["table",
       5 ,
       4,
       "chair",
       8,
       "chair"]

EXERCISE: try writing the list above WITHOUT putting a comma after the 5, which error appears?

[14]:
# write here


A list can also contain other lists:

[15]:
table = [  ['a','b','c'],  ['d','e','f']  ]

Typically, whenver we have structures like this, it’s convenient to displace them on many rows (it’s not mandatory but improves clarity):

[16]:
table = [                 # start external big list
          ['a','b','c'],    # internal list 1
          ['d','e','f']     # internal list 2
        ]                 # end external big list
[17]:
table
[17]:
[['a', 'b', 'c'], ['d', 'e', 'f']]

Let’s see how it is shown in Python Tutor:

[18]:
table = [
          ['a','b','c'],
          ['d','e','f']
        ]

jupman.pytut()
[18]:

As we previously said, in a list we can put the elements we want, so we can mix lists with different dimensions, strings, numbers and so on:

[19]:
so_much = [
            ['hello',3,'world'],
            'a string',
            [9,5,6,7,3,4],
            8,
          ]
[20]:
print(so_much)
[['hello', 3, 'world'], 'a string', [9, 5, 6, 7, 3, 4], 8]

Let’s see how it appears in Python Tutor:

[21]:
so_much = [
             ['hello',3,'world'],
             'a string',
             [9,5,6,7,3,4],
             8,
          ]

jupman.pytut()
[21]:

Empty list

There are two ways to create an empty list.

  1. with square brackets:

[22]:
my_empty_list = []
[23]:
my_empty_list
[23]:
[]
  1. Or with list():

[24]:
another_empty_list = list()
[25]:
another_empty_list
[25]:
[]

WARNING: When you create an empty list (independently from the used notation), a NEW region in memory is allocated to place the list.

Let’s see what this means with Python Tutor:

[26]:
a = []
b = []

jupman.pytut()
[26]:

Note two arrows appeared, which point to different memory regions. The same would have happend by initializing the lists with some elements:

[27]:
la = [8,6,7]
lb = [9,5,6,4]

jupman.pytut()
[27]:

We would have two lists in different memory regions also by placing identical elements inside the lists:

[28]:
la = [8,6,7]
lb = [8,6,7]

jupman.pytut()
[28]:

Things get complicated when we start using assignment operations:

[29]:
la = [8,6,7]
[30]:
lb = [9,5,6,4]
[31]:
lb = la

By writing lb = la, we told Python to ‘forget’ the previous assignment of lb to [9,5,6,4], and instead to associate lb to the same value associated to la, that is [8,6,7]. Thus, in memory we will see an arrow departing from lb and arriving into [8,6,7], and the memory region where the list [9,5,6,4] was placed will be removed (won’t be associated to any variable anymore). Let’s see what happens with Python Tutor:

[32]:
la = [8,6,7]
lb = [9,5,6,4]
lb = la

jupman.pytut()
[32]:

EXERCISE: Try swapping the lists associated to variables la and lb by using only assignments and without creating new lists. If you want, you can overwrite a third variable lc. Verify what happes with Python Tutor.

  • your code must work for any value of la, lb and lc

Example - given:

la = [9,6,1]
lb = [2,3,4,3,5]
lc = None

After your code, it must result:

>>> print(la)
[2,3,4,3,5]
>>> print(lb)
[9,6,1]
Show solution
[33]:
la = [9,6,1]
lb = [2,3,4,3,5]
lc = None

# write here


QUESTION: Have a look at these two pieces of code. For each case, try thinking how they might be represented in memory and then verify with Python Tutor.

  • could there be a difference?

  • how many memory cells will be allocated in total?

  • how many arrows will you see?

# first case
lb = [
       [8,6,7],
       [8,6,7],
       [8,6,7],
       [8,6,7],
     ]
# second case
la = [8,6,7]
lb = [
       la,
       la,
       la,
       la
     ]
[34]:
# first case
lb = [
       [8,6,7],
       [8,6,7],
       [8,6,7],
       [8,6,7],
     ]
jupman.pytut()
[34]:
[35]:
# second case

la = [8,6,7]
lb = [
       la,
       la,
       la,
       la
     ]
jupman.pytut()
[35]:
Show answer

Exercise - create lists 1

Given two variables:

la = [4,3]
lb = [9,6,7]

Write some code which prints the list [[4, 3], [[9, 6, 7], [4, 3], [9, 6, 7]], [4, 3]]

  • DO NOT write numbers, use only lists of variables

Show solution
[36]:
la = [4,3]
lb = [9,6,7]

# write here


[[4, 3], [[9, 6, 7], [4, 3], [9, 6, 7]], [4, 3]]

Exercise - create lists 2

Insert some values in the lists la, lb such that

print([[la,la],[lb,la]])

prints

[[[8, 4], [8, 4]], [[4, 8, 4], [8, 4]]]
  • Insert only NUMBERS

  • Observe in Python Tutor how arrows are represented

[37]:
la = []  # insert numbers
lb = []  # insert numbers

print([[la,la],[lb,la]])
[[[], []], [[], []]]
Show solution
[38]:

Exercise - create lists 3

Insert some values as elements of the lists la, lb e lc such that

print([[lb,lb,[lc,la]],lc])

prints

[[[8, [7, 7]], [8, [7, 7]], [[8, 7], [8, 5]]], [8, 7]]
  • insert only NUMBERS or NEW LISTS OF NUMBERS

  • Observe in Python Tutor are arrows are represented

[39]:

la = []  # insert elements  (numbers or lists of numbers)
lb = []  # insert elements  (numbers or lists of numbers)
lc = []  # insert elements  (numbers or lists of numbers)

print([[lb,lb,[lc,la]],lc])
[[[], [], [[], []]], []]
Show solution
[40]:

Exercise - create lists 4

Insert some values in the lists la, lb such that

print([[la,lc,la], lb])

prints

[[[3, 2], [[3, 2], [8, [3, 2]]], [3, 2]], [8, [3, 2]]]
  • insert only NUMBERS or VARIABLES la,lb or lc

  • Observe in Python Tutor how arrows are represented

[41]:
la = []  # insert numbers or variables la, lb, lc
lb = []  # insert numbers or variables la, lb, lc
lc = []  # insert numbers or variables la, lb, lc

print([[la,lc,la], lb])
[[[], [], []], []]
Show solution
[42]:

Convert sequences into lists

list may also be used to convert any sequence into a NEW list. A sequence type we’ve alredy seen are strings, so we can check what happens when we use list like it were a function and we pass a string as parameter:

[43]:
list("train")
[43]:
['t', 'r', 'a', 'i', 'n']

We obtained a list in which each element is made of a character from the original string.

What happens if we call instead list on another list?

[44]:
list( [7,9,5,6] )
[44]:
[7, 9, 5, 6]

Apparently, nothing particular, we obtained a list with the same start elements. But is it really the same list? Let’s have a better look with Python Tutor:

[45]:
la = [7,9,5,6]

lb = list( la )

jupman.pytut()
[45]:

We note a NEW memory region was created with the same elements of la.

Exercise - gulp

Given a string with mixed uppercase and lowercase characters, write some code which creates a list containing as first element a list with characters from the string lowercased and as second element a list containing all the uppercased characters

  • your code must work with any string

  • if you don’t remember the string methods, look here

Example - given:

s = 'GuLp'

your code must print:

[['g', 'u', 'l', 'p'], ['G', 'U', 'L', 'P']]
Show solution
[46]:
s = 'GuLp'

# write here


[['g', 'u', 'l', 'p'], ['G', 'U', 'L', 'P']]

QUESTION: This code:

  • produces an error or assigns something to x ?

  • After its execution, how many lists remain in memory?

  • Can we shorten it?

s = "marathon"
x = list(list(list(list(s))))
Show answer

QUESTION: This code:

  • produces an error or assigns something to x ?

  • After its execution, how many lists remain in memory?

s = "chain"
a = list(s)
b = list(a)
c = b
x = list(c)
Show answer

Exercise - garaga

Given

sa = "ga"
sb = "ra"
la = ['ga']
lb = list(la)
  • Assign to lc a list built in such a way so that once printed produces:

>>> print(lc)
[['g', 'a', 'r', 'a'], ['ga'], ['ga'], ['r', 'a', 'g', 'a']]
  • in Python Tutor, ALL the arrows must point to a different memory region

[47]:
sa = "ga"
sb = "ra"
la = ['ga']
lb = list(la)

# insert come code in the list
lc = []

print(lc)
jupman.pytut()
[]
[47]:
Show solution
[48]:

[['g', 'a', 'r', 'a'], ['ga'], ['ga'], ['r', 'a', 'g', 'a']]
[48]:

References

Continue

Go on reading notebook Lists 2 - operators

[ ]: