Tuple

Download exercise zip

Browse files online

A tuple in Python is an immutable sequence of heterogenous elements which allows duplicates, so we can put inside the objects we want, of different types, and with repetitions.

What to do

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

tuples
    tuples.ipynb
    tuples-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 tuples.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 tuples

Tuples are created with round parenthesis () and by separating the elements with commas ,

Some example:

[2]:
numbers = (6,7,5,7,7,9)
[3]:
print(numbers)
(6, 7, 5, 7, 7, 9)

Tuples of one element: You can create a tuple of a single element by adding a comma after the element:

[4]:
little_tup = (4,)  # notice the comma !!!

Let’s verify the type is the expected one:

[5]:
type(little_tup)
[5]:
tuple

To see the difference, we write down here (4) without comma and we verify the type of the obtained object:

[6]:
fake = (4)
[7]:
type(fake)
[7]:
int

We see that fake is an int, because 4 has been evaluated as an expression inside round brackets so the result is the content inside the parenthesis.

Empty tuple

We can also create an empty tuple:

[8]:
empty = ()
[9]:
print(empty)
()
[10]:
type(empty)
[10]:
tuple

Tuples without brackets

When we assign values to some variable, (and only when we assign values to variables) it is possible to use a notation like the following, in which on the left of = we put names of variables and on the right we place a sequence of values:

[11]:
a,b,c = 1, 2, 3
[12]:
a
[12]:
1
[13]:
b
[13]:
2
[14]:
c
[14]:
3

If we ask ourselves what that 1,2,3 is, we can try putting on the left a single variable:

[15]:
# WARNING: BETTER AVOID THIS!
x = 1,2,3
[16]:
type(x)
[16]:
tuple

We see that Python considered that 1,2,3 as a tuple. Typically, you would never write assignments with less variables than values to put, but if it happens, probably you will find yourself with some undesired tuple !

QUESTION: Have a look at the following code snippets, and for each try guessing which result it produces (or if it gives an error)

  1. z,w = 5,6
    print(type(z))
    print(type(w))
    
  2. a,b = 5,6
    a,b = b,a
    print('a=',a)
    print('b=',b)
    
  3. z = 5,
    print(type(z))
    
  4. z = ,
    print(type(z))
    

Heterogenous elements

In a tuple we can put elements of different types, like numbers and strings:

[17]:
stuff = (4, "paper", 5, 2,"scissors", 7)
[18]:
stuff
[18]:
(4, 'paper', 5, 2, 'scissors', 7)
[19]:
type(stuff)
[19]:
tuple

We can also insert other tuples:

[20]:
salad = ( ("lettuce", 3), ("tomatoes",9), ("carrots",4) )
[21]:
salad
[21]:
(('lettuce', 3), ('tomatoes', 9), ('carrots', 4))
[22]:
type(salad)
[22]:
tuple

And also lists:

[23]:
mix = ( ["when", "it", "rains"], ["I", "program"], [7,3,9] )

WARNING: avoid mutable objects inside tuples!

Inserting mutable objects like lists inside tuples may cause problems in some situations like when you later want to use the tuple as element of a set or a key in a dictionary (we will see the details in the respective tutorials)

Let’s see how the previous examples are represented in Python Tutor:

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

import jupman
[25]:
stuff = (4, "paper", 5, 2,"scissors", 7)
salad = ( ("lettuce", 3), ("tomatoes",9), ("carrots",4) )
mix = ( ["when", "it", "rains"], ["I", "program"], [7,3,9] )

jupman.pytut()
[25]:

Creating tuples from sequences

You can create a tuple from any sequence, like for example a list:

[26]:
tuple( [8,2,5] )
[26]:
(8, 2, 5)

Or a string (which is a character sequence):

[27]:
tuple("abc")
[27]:
('a', 'b', 'c')

Creating sequences from tuples

Since the tuple is a sequence, it is also possible to generate lists from tuples:

[28]:
list( (3,4,2,3)  )
[28]:
[3, 4, 2, 3]

QUESTION: Does is it make sense creating a tuple from another tuple like this? Can we rewrite the code in a more concise way?

[29]:
x = (4,2,5)
y = tuple(x)
Show answer

QUESTION: Have a look at the following expressions, and for each try to guess which result produces (or if it gives an error):

  1. (1.2,3.4)
    
  2. (1;2;3;4)
    
  3. (1,2;3,4)
    
  4. (1,2,3,4)
    
  5. (())
    
  6. type(())
    
  7. ((),)
    
  8. tuple([('a'),('b'),('c')])
    
  9. tuple(tuple(('z','u','m')))
    
  10. str(('a','b','c'))
    
  11. "".join(('a','b','c'))
    

Operators

The following operators work on tuples and behave exactly as in lists:

Operator

Result

Meaning

len(tuple)

int

Return the length of a tuple

tuple[int]

object

Reads an element at specified index

tuple[int:int]

tuple

Extracts a sub-tuple - return a NEW tuple

tuple + tuple

tuple

Concatenates two tuples - return a NEW tuple

obj in tuple

bool

Checks whether an element is present in a tuple

tuple * int

tuple

Replicates the tuple - return a NEW tuple

==,!=

bool

Checks if two tuples are equal or different

len

len function returns the tuple length:

[30]:
len( (4,2,3) )
[30]:
3
[31]:
len( (7,) )
[31]:
1
[32]:
len( () )
[32]:
0

QUESTION: Have a look at following expressions, and for each try to guess the result (or if it gives an error)

  1. len(3,2,4)
    
  2. len((3,2,4))
    
  3. len(('a',))
    
  4. len(('a,'))
    
  5. len(((),(),()))
    
  6. len(len((1,2,3,4)))
    
  7. len([('d','a','c','d'),(('ab')),[('a','b','c')]])
    
[ ]:

Reading an element

Like in strings and lists by using brackets we can read an element at a certain position:

[33]:
#      0  1  2  3
tup = (10,11,12,13)
[34]:
tup[0]
[34]:
10
[35]:
tup[1]
[35]:
11
[36]:
tup[2]
[36]:
12
[37]:
tup[3]
[37]:
13

We can also use negative indexes:

[38]:
tup[-1]
[38]:
13

QUESTION: Have a look at the following expressions and for each of them try to guess the result or if it produces an error:

  1. (1,2,3)[0]
    
  2. (1,2,3)[3]
    
  3. (1,2,3)0
    
  4. ()[0]
    
  5. (())[0]
    
  6. type((())[0])
    
  7. ('a,')[0]
    
  8. ('a',)[0]
    
  9. (1,2,3)[-0]
    
  10. (1,2,3)[-1]
    
  11. (1,2,3)[-3]
    
[ ]:

Exercise - animals

Given the string animals = "Siamese cat,dog,canary,piglet,rabbit,hamster"

  1. convert it to a list

  2. create a tuple of tuples where each tuple has two elements: the animal name and the name length, i.e. ((“dog”,3), ( “hamster”,7))

  3. print the tuple

You should obtain:

Siamese cat,dog,canary,piglet,rabbit,hamster

(('Siamese cat', 11), ('dog', 3), ('canary', 6), ('piglet', 6), ('rabbit', 6), ('hamster', 7))
  • you can assume animals always contains exactly 6 animals

Show solution
[39]:
animals = "Siamese cat,dog,canary,piglet,rabbit,hamster"

# write here



Slices

As with strings and lists, by using slices we can also extract subsequences from a tuple, that is, on the right of the tuple we can write square brackets with inside a start index INCLUDED, a colon : and an end index EXCLUDED:

[40]:
tup = (10,11,12,13,14,15,16,17,18,19)
[41]:
tup[2:6]  # from index 2 INCLUDED to 6 EXCLUDED
[41]:
(12, 13, 14, 15)

It is possible to alternate the gathering of elements by adding the number of elements to skip as a third numerical parameter in the square brackets, for example:

[42]:
tup = (10,11,12,13,14,15,16,17)
[43]:
tup[0:8:5]
[43]:
(10, 15)
[44]:
tup[0:8:2]
[44]:
(10, 12, 14, 16)
[45]:
tup[1:8:1]
[45]:
(11, 12, 13, 14, 15, 16, 17)

WARNING: remeber that slices produce a NEW tuple !

QUESTION: Have a look at the following code snippets, and for each try to guess which result it produces (or if it gives an error)

  1. (7,6,8,9,5)(1:3)
    
  2. (7,6,8,9,5)[1:3]
    
  3. (10,11,12,13,14,15,16)[3:100]
    
  4. (10,11,12,13,14,15,16)[-3:5]
    
  5. (1,0,1,0,1,0)[::2]
    
  6. (1,2,3)[::1]
    
  7. (1,0,1,0,1,0)[1::2]
    
  8. tuple("postcards")[0::2]
    
  9. (4,5,6,3,4,7)[0:::2]
    

Concatenation

It is possible to concatenate two tuples by using the operator +, which creates a NEW tuple:

[46]:
t = (1,2,3) + (4,5,6,7,8)
[47]:
t
[47]:
(1, 2, 3, 4, 5, 6, 7, 8)
[48]:
type(t)
[48]:
tuple

Let’s verify that original tuples are not modified:

[49]:
x = (1,2,3)
y = (4,5,6,7,8)
[50]:
t = x + y
[51]:
t
[51]:
(1, 2, 3, 4, 5, 6, 7, 8)
[52]:
x
[52]:
(1, 2, 3)
[53]:
y
[53]:
(4, 5, 6, 7, 8)

Let’s see how they are represented in Python Tutor:

[54]:
x = (1,2,3)
y = (4,5,6,7,8)
t = x + y
print(t)
print(x)
print(y)

jupman.pytut()
(1, 2, 3, 4, 5, 6, 7, 8)
(1, 2, 3)
(4, 5, 6, 7, 8)
[54]:

QUESTION: Have a look at the following code snippets, and for each try to guess which result it produces (or if it gives an error)

  1. ()+()
    
  2. type(()+())
    
  3. len(()+())
    
  4. ()+[]
    
  5. []+()
    
  6. (2,3,4) + tuple([5,6,7])
    
  7. "crazy"+('r','o','c','k','e','t')
    

Membership

As in all sequences, if we want to verify whether an element is contained in a tuple we can use the operator in which returns a boolean value:

[55]:
'e' in ('h','e','l','m','e','t')
[55]:
True
[56]:
'z' in ('h','e','l','m','e','t')
[56]:
False

not in

To check whether something is not belonging to a tuple, we can use two forms:

not in - form 1:

[57]:
"carrot" not in ("watermelon","banana","apple")
[57]:
True
[58]:
"watermelon" not in ("watermelon","banana","apple")
[58]:
False

not in - form 2

[59]:
not "carrot" in ("watermelon","banana","apple")
[59]:
True
[60]:
not "watermelon" in ("watermelon","banana","apple")
[60]:
False

QUESTION: Have a look at the following code snippets, and for each try to guess which result it produces (or if it gives an error)

  1. 3 in (1.0, 2.0,3.0)
    
  2. 3.0 in (1,2,3)
    
  3. 3 not in (3)
    
  4. 3 not in (3,)
    
  5. 6 not in ()
    
  6. 0 in (0)[0]
    
  7. [] in ()
    
  8. () in []
    
  9. not [] in ()
    
  10. () in ()
    
  11. () in (())
    
  12. () in ((),)
    
  13. 'ciao' in ('c','i','a','o')
    
[ ]:

Multiplication

To replicate the elements in a tuple, it is possible to use the operator * which produces a NEW tuple:

[61]:
(7,8,5) * 3
[61]:
(7, 8, 5, 7, 8, 5, 7, 8, 5)
[62]:
(7,8,5) * 1
[62]:
(7, 8, 5)
[63]:
(7,8,5) * 0
[63]:
()

QUESTION: What is the following code going to print?

x = (5,6,7)
y = x * 3
print('x=',x)
print('y=',y)

ANWSER: It will print:

x = (5, 6, 7)
y = (5, 6, 7, 5, 6, 7, 5, 6, 7)

because the multiplication generates a NEW tuple which is associated to y. The tuple associated to x remains unchanged.

QUESTION: Have a look at the following expressions, and for each try to guess which result it produces (or if it gives an error)

  1. (5,6,7)*(3.0)
    
  2. (5,6,7)*(3,0)
    
  3. (5,6,7)*(3)
    
  4. (5,6,7)*3
    
  5. (4,2,3)*int(3.0)
    
  6. (1,2)*[3][0]
    
  7. (1,2)*(3,4)[-1]
    
  8. [(9,8)]*4
    
  9. (1+2,3+4)*5
    
  10. (1+2,)*4
    
  11. (1+2)*4
    
  12. (1,2,3)*0
    
  13. (7)*0
    
  14. (7,)*0
    
[ ]:

Exercise - welcome

Given a tuple x containing exactly 3 integers, and a tuple y containing exactly 3 tuples of characters, write some code to create a tuple z containing each tuple of y replicated by the corresponding integer in x.

Example - given:

x = (2,4,3)
y = (('w','e','l','c'),('o',),('m','e'))

after your code it should print:

>>> print(z)
('w', 'e', 'l', 'c', 'w', 'e', 'l', 'c', 'o', 'o', 'o', 'o', 'm', 'e', 'm', 'e', 'm', 'e')
Show solution
[64]:
x = (2,4,3)
y = (('w','e','l','c'),('o',),('m','e'))

# write here


('w', 'e', 'l', 'c', 'w', 'e', 'l', 'c', 'o', 'o', 'o', 'o', 'm', 'e', 'm', 'e', 'm', 'e')

Write an element

Tuples are immutable, so trying to i.e. write an assignment for placing the number 12 into the cell at index 3 provokes an error:

#      0 1 2 3 4
tup = (5,8,7,9,11)
tup[3] = 666

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-118-83949b0c81e2> in <module>
      1 tup = (5,8,7,9,11)
----> 2 tup[3] = 666

TypeError: 'tuple' object does not support item assignment

What we can do is to create a NEW tuple by composing it from sequences takes from the original one:

[65]:
#      0  1  2  3  4  5  6
tup = (17,54,34,87,26,95,34)
[66]:
tup =  tup[0:3] + (12,) + tup[4:]
[67]:
tup
[67]:
(17, 54, 34, 12, 26, 95, 34)

WARNING: append, extend, insert, sort DO NOT WORK WITH TUPLES !

All the methods you used to modify lists will not work with tuples.

Exercise - badmod

Try writing down here (1,2,3).append(4) and see which error appears:

Show solution
[68]:
# write here


Exercise - abde

Given a tuple x, save in a variable y another tuple containing:

  • at the beginning, the same elements of x except the last one

  • at the end, the elements 'd' and 'e' .

  • Your code should work with any tuple x

Example - given:

x = ('a','b','c')

after your code, you should see printed:

x = ('a', 'b', 'c')
y = ('a', 'b', 'd', 'e')
Show solution
[69]:
x = ('a','b','c')

# write here


Exercise - charismatic

Given a tuple t having alternating uppercase / lowercase characters, write some code which modifies the assignment of t so that t becomes equal to a tuple having all characters lowercase as first ones and all uppercase characters as last ones.

Example - given:

t = ('C', 'h','A', 'r', 'I', 's', 'M', 'a', 'T', 'i', 'C')

after your code it must result:

>>> print(t)
('C', 'A', 'I', 'M', 'T', 'C', 'h', 'r', 's', 'a', 'i')
Show solution
[70]:
t = ('C', 'h','A', 'r', 'I', 's', 'M', 'a', 'T', 'i', 'C')

# write here


Exercise - sorting

Given a tuple x of unordered numbers, write some code which changes the assignment of x so that x results assigned to a sorted tuple

  • your code must work for any tuple x

  • HINT: as we’ve already written, tuples DO NOT have sort method (because it would mutate them), but lists have it …

Example - given:

x = (3,4,2,5,5,5,2,3)

after your code it must result:

>>> print(x)
(2, 2, 3, 3, 4, 5, 5, 5)
Show solution
[71]:
x = (3,4,2,5,5,5,2,3)

# write here


Methods

Tuples are objects of type typle and have methods which allows to operate on them:

Method

Return

Description

tuple.index(obj)

int

Searches for the first occurence of an element and returns its position

tuple.count(obj)

int

Count the occurrences of an element

index method

index method allows to find the index of the FIRST occurrence of an element.

[72]:
tup = ('b','a','r','a','t','t','o')
[73]:
tup.index('b')
[73]:
0
[74]:
tup.index('a')
[74]:
1
[75]:
tup.index('t')
[75]:
4

If the element we’re looking for is not present, we will get an error:

>>> tup.index('z')

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-318-96cf33478b69> in <module>
----> 1 tup.index('z')

ValueError: tuple.index(x): x not in tuple

QUESTION: Have a look at the following expressions, and for each try to guess which result (or if it gives an error)

  1. (3,4,2).index(4)
    
  2. (3,4,---1).index(-1)
    
  3. (2.2,.2,2,).index(2)
    
  4. (3,4,2).index(len([3,8,2,9]))
    
  5. (6,6,6).index(666)
    
  6. (4,2,3).index(3).index(3)
    
  7. tuple("GUG").index("g")
    
  8. (tuple("ci") + ("a","o")).index('a')
    
  9. (()).index(())
    
  10. ((),).index(())
    

count method

We can obtain the number of occurrences of a certain element in a list by using the method count:

[76]:
t = ('a', 'c', 'a', 'd', 'e', 'm', 'i', 'a')
[77]:
t.count('a')
[77]:
3
[78]:
t.count('d')
[78]:
1

If an element is not present 0 is returned:

[79]:
t.count('z')
[79]:
0

Exercise - fruits

Given the string s = "apple|pear|apple|cherry|pear|apple|pear|pear|cherry|pear|strawberry"

Insert the elements separated by "|" (pipe character) in a list.

  1. How many elements must the list have?

  2. Knowing the list created at previous point has only four distinct elements (es "apple", "pear", "cherry", and "strawberry"), create another list where each element is a tuple containing the name of the fruit and its multiplicity (that is, the number of times it appears in the original list).

Example - given:

counts = [("apple", 3), ("pear",5), ...]

Here you can write code which works given a specific constant, so you don’t need cycles.

  1. Print the content of each tuple in a separate line (i.e.: first libe; "apple" is present 3 times)

You should obtain:

[('apple', 3), ('pear', 5), ('cherry', 2), ('strawberry', 1)]

apple is present 3 times
pear is present 5 times
cherry is present 2 times
strawberry is present 1 times
Show solution
[80]:
s = "apple|pear|apple|cherry|pear|apple|pear|pear|cherry|pear|strawberry"

# write here


[('apple', 3), ('pear', 5), ('cherry', 2), ('strawberry', 1)]

apple is present 3 times
pear is present 5 times
cherry is present 2 times
strawberry is present 1 times

Exercises with functions

WARNING: following exercises require to know:

If you are just a beginner, you may skip them and come back later.

Exercise - touples

✪✪ Let’s call a touple a tuple with a couple of elements. Write a function touples which given a tuple, RETURNs a list having as elements touples each taken in alternation from t.

  • if the input tuple t has an odd number of elements, the last tuple in the list to return will be made of only one element

Example:

>>> touples( ('c', 'a', 'r', 'p', 'e', 't') )   # even length
[('c', 'a'), ('r', 'p'), ('e', 't')]
>>> touples( ('s','p','i','d','e','r','s') )    # odd length
[('s', 'p'), ('i', 'd'), ('e', 'r'), ('s',)]
Show solution
[81]:
# write here


Exercise - joined

✪✪ Write a function which given two tuples of characters ta and tb having each different characters (may also be empty), return a tuple made like this:

  • if the tuple ta terminates with the same character tb begins with, RETURN the concatenation of ta and yb WITHOUT duplicated characters

  • otherwise RETURN an empty tuple

Example:

>>> joined(('a','b','c'), ('c','d','e'))
('a', 'b', 'c', 'd', 'e')
>>> joined(('a','b'), ('b','c','d'))
('a', 'b', 'c', 'd')
>>> joined((),('e','f','g'))
()
>>> joined(('a',),('e','f','g'))
()
>>> f(('a','b','c'),())
()
>>> f(('a','b','c'),('d','e'))
()
Show solution
[82]:
# write here


Verify comprehension

WARNING

The following exercises contain tests with assert. To understand how to do them, read first Error handling and testing

doubles

✪✪ Take as input a list of n integer numbers, and RETURN a NEW list which contains n tuples each having two elements. Each tuple contains a number taken from the corresponding position in the original list, and its double.

Example - given:

doubles([ 5, 3, 8])

it must produce the list:

[(5,10), (3,6), (8,16)]
Show solution
[83]:
def doubles(lst):
    raise Exception('TODO IMPLEMENT ME !')

# TEST START - DO NOT TOUCH !
assert doubles([]) == []
assert doubles([3]) == [(3,6)]
assert doubles([2,7]) == [(2,4),(7,14)]
assert doubles([5,3,8]) == [(5,10), (3,6), (8,16)]

# verify the original list was not changed
la = [6]
lb = doubles(la)
assert la == [6]
assert lb == [(6,12)]
# TEST END

nasty

✪✪✪ Given two tuples ta and b, ta made of characters and tb of positive integer numbers , write a function nasty which RETURNS a tuple having two character strings: the first character is taken from ta, the second is a number taken from the corresponding position in tb. The strings are repeated for a number of times equal to that number.

>>> nasty(('u','r','g'), (4,2,3))
('u4', 'u4', 'u4', 'u4', 'r2', 'r2', 'g3', 'g3', 'g3')

>>> nasty(('g','a','s','p'), (2,4,1,3))
('g2', 'g2', 'a4', 'a4', 'a4', 'a4', 's1', 'p3', 'p3', 'p3')
Show solution
[84]:
# write here


References

[ ]: