Tuples

The Python tuple is an alternative to the list structure. The example below shows how to construct a tuple.

contact = ('Joe Gregg','832-6736')

Unlike lists, which can have items appended or removed from them via the use of list methods, the tuple is an immutable structure. The tuple in the example above has two items in it: this size is fixed and can never be changed.

You can access the elements in a tuple using the same index notation you would use with a list.

phone = contact[1]

You can also update the entries in a tuple by assigning new values to them.

contact[1] = '555-1212'

An example

Tuples are especially useful in situations where data items belong together and would not make sense by themselves.

Here is an example. The list below shows currency codes for a number of currencies and the exchange rate from US dollars to that currency. The numbers in each case show how many units of the currency one US dollar would buy.

exchange = [('EUR' , 0.869335) , ('JPY' , 113.0005) ,\
('GBP' , 0.760425) , ('AUD' , 1.40553) , ('CAD' , 1.29406) ,\
('CHF' , 0.99148) , ('CNY' , 6.9228) , ('SEK' , 9.09429) ,\
('NZD' , 1.54148) , ('MXN' , 18.99626) , ('SGD' , 1.3809)]

Because the list spans multiple lines, I have used the Python continuation character, \, at the end of each line.

Suppose we wanted to write a program that prompts the user to enter a code for a foreign currency and an amount of that currency that the user wants to purchase. The program will compute and print how many US dollars it would take to purchase that many units of the currency. Here some code that will do this.

exchange = [('EUR' , 0.869335) , ('JPY' , 113.0005) ,\
('GBP' , 0.760425) , ('AUD' , 1.40553) , ('CAD' , 1.29406) ,\
('CHF' , 0.99148) , ('CNY' , 6.9228) , ('SEK' , 9.09429) ,\
('NZD' , 1.54148) , ('MXN' , 18.99626) , ('SGD' , 1.3809)]
code = input('Enter a currency code: ')
amount = float(input('How many units do you want to buy? ')

cost = 0
for pair in exchange:
  if pair[0] == code:
    cost = amount/pair[1]

if cost != 0:
  print('Your cost is $'+str(cost))
else:
  print('You did not enter a valid code.')

An alternative to using the index notation for tuples in a for loop is to use a form of the for loop that assigns each member of a tuple to a different loop variable:

for c,r in exchange:
  if c == code:
    cost = amount/r

Zip lists

Sometimes you will want to combine data from two separate lists into a single list. A common situation where you might want to do this is printing a table.

In an earlier lecture I showed some code to print a list of data points in a table. Here is the original code.

x = [1935,1940,1945,1950,1955,1960,1965,1970,1975,1980]
y = [32.1,30.5,24.4,23,19.1,15.6,12.4,9.7,8.9,7.2]
print(' Year Population')
for i in range(0,len(x)):
  print('{:5d}    {:>4.1f}'.format(x[i],y[i]))

This code iterates over a list of index values and uses those index values to access elements of both lists.

An alternative approach is to construct a zip list from the original pair of lists and just iterate over that. A zip list formed from a pair of lists is a single lists of tuples, with each pair of data items from the original lists becoming one tuple in the zip list. Here is the table printing example rewritten to use a zip list:

x = [1935,1940,1945,1950,1955,1960,1965,1970,1975,1980]
y = [32.1,30.5,24.4,23,19.1,15.6,12.4,9.7,8.9,7.2]
data = list(zip(x,y))
print(' Year Population')
for year,pop in data:
  print('{:5d}    {:>4.1f}'.format(year,pop))

List comprehensions

A Python list comprehension is a method for constructing a list from a list, a range, or other iterable structure. List comprehensions are frequently used to extract data from other lists or to generate new data from an existing data list.

Here is an example. Suppose we wanted to make a list of just the currency codes from the example above. We could do this by using a combination of a loop and the list append() method.

allCodes = []
for c,r in exchange:
  allCodes.append(c)

A list comprehension provides a more compact way to accomplish the same thing.

allCodes = [c for r,c in exchange]

Another common application of list comprehensions is making lists from ranges. For example, if we wanted to make a list of powers of 2 we could use the following code:

powers = [2**n for n in range(0,10)]

Here is a more sophisticated example. A currency cross rate is an exchange rate from one currency to another, with an origin currency and a destination currency. We can use our list of US dollar exchange rates to make cross rates for any pair of currencies in the exchange list. For example, if we wanted to set up an exchange from GBP to CNY, we would first convert 1 GBP to 1/0.760425 dollars. We would then convert 1/0.760425 dollars to (1/0.760425)*6.9228 CNY.

Here is a list comprehension that makes a table of all possible cross rates. This is a nested set of list comprehensions, where the outer comprehension uses an inner comprehension to make lists of cross rates, producing a list of lists as the final result.

crosses =[[(o,d,r2/r1) for d,r2 in exchange] for o,r1 in exchange]

Here is one final thing we should do with the resulting table. The diagonal entries represent exchanges where the origin currency and the destination currency are the same. We should go in and set all of those cross rates to be exactly 1. Here is a for loop that can do this.

for i in range(0,len(crosses)):
  crosses[i][i][2] = 1

Programming assignment

Redo assignment two using tuples. Start your program with the statements

x = [1935,1940,1945,1950,1955,1960,1965,1970,1975,1980]
y = [32.1,30.5,24.4,23,19.1,15.6,12.4,9.7,8.9,7.2]
data = list(zip(x,y))

and then do everything else in the rest of the program using the data list. Try not to use the x list or the y list in any of the following code: do everything with the data list.

Also, include at least one list comprehesion in your program. The list of residuals is a good candidate for this: try building this list with a list comprehension instead of a loop.