# Tuples¶

We’ll look at tuple from a number of viewpoints: semantics, literal values, operations, comparison operators, statements, built-in functions and methods.

Additionally, we have a digression on the operator in Digression on The Sigma Operator.

## Tuple Semantics¶

A tuple is a container for a fixed sequence of data objects. The name comes from the Latin suffix for multiples: double, triple, quadruple, quintuple.

Mathematicians commonly consider ordered pairs; for instance, most analytical geometry is done with Cartesian coordinates (x, y ). An ordered pair can be generalized as a 2-tuple.

An essential ingredient here is that a tuple has a fixed and known number of elements. A 3-dimensional point is a 3-tuple. An CMYK color code is a 4-tuple. The size of the tuple can’t change without fundamentally redefining the problem we’re solving.

A tuple is an immutable sequence of Python objects. Since it is a sequence, all of the common operations to sequences apply. Since it is immutable, it cannot be changed. Two common questions that arise are how to expand a tuple and how to remove objects from a tuple.

When someone asks about changing an element inside a tuple, either adding, removing or updating, we have to remind them that the list, covered in Lists, is for dynamic sequences of elements. A tuple is generally applied when the number of elements is fixed by the nature of the problem.

This tuple processing even pervades the way functions are defined. We can have positional parameters collected into a tuple, something we’ll cover in Advanced Parameter Handling For Functions.

## Tuple Literal Values¶

A tuple literal is created by surrounding objects with () and separating the items with commas (,). An empty tuple is simple ().

An interesting question is how Python tells an expression from a 1-tuple. A 1-element tuple has a single comma; for example, (1,). An expression lacks the comma: (1). A pleasant consequence of this is that an extra comma at the end of every tuple is legal; for example, (9, 10, 56, ).

Examples:

xy= (2, 3)
personal= ('Hannah',14,5*12+6)
singleton= ("hello",)

xy: A 2-tuple with integers. A 3-tuple with a string and two integers A 1-tuple with a string. The trailing , assures that his is a tuple, not an expression.

The elements of a tuple do not have to be the same type. A tuple can be a mixture of any Python data types, including other tuples.

## Tuple Operations¶

There are three standard sequence operations (+, *, []) that can be performed with tuples as well as other sequences.

The + operator creates a new tuple as the concatenation of the arguments. Here’s an example.

>>> ("chapter",8) + ("strings","tuples","lists")
('chapter', 8, 'strings', 'tuples', 'lists')


The * operator between tuple and number (number * tuple or tuple * number) creates a new tuple that is a number of repetitions of the input tuple.

>>> 2*(3,"blind","mice")
(3, 'blind', 'mice', 3, 'blind', 'mice')


The [] operator selects an item or a slice from the tuple.

There are two forms: the single-item form and the slice form.

• The single item format is tuple [ index ]. Items are numbered from 0 to len(tuple). Items are also numbered in reverse from -len(tuple) to -1.

• The slice format is tuple [ start : end ]. Items from start to end -1 are chosen to create a new tuple as a slice of the original tuple; there will be items in the resulting tuple.

If start is omitted it is the beginning of the tuple (position 0).

If end is omitted it is the end of the tuple (position -1).

Yes, you can omit both (someTuple[:]) to make a copy of a tuple. This is a shallow copy: the original objects are now members of two distinct tuples.

>>> t=( (2,3), (2,"hi"), (3,"mom"), 2+3j,    6.02E23 )
>>> t[2]
(3, 'mom')
>>> t[:3]
((2, 3), (2, 'hi'), (3, 'mom'))
>>> t[3:]
((2+3j), 6.02e+23)
>>> t[-1]
6.02e+23
>>> t[-3:]
((3, 'mom'), (2+3j), 6.02e+23)


## Tuple Comparison Operations¶

The standard comparisons (<, <=, >, >=, ==, !=, in, not in) work exactly the same among tuple objects as they do among string and other sequences. The tuple pbjects are compared element by element. If the corresponding elements are the same type, ordinary comparison rules are used. If the corresponding elements are different types, the type names are compared, since there is almost no other rational basis for comparison.

>>> a = (1, 2, 3, 4, 5)
>>> b = (9, 8, 7, 6, 5)
>>> a < b
True
>>> 3 in a
True
>>> 3 in b
False


Here’s a longer example.

redblack.py

#!/usr/bin/env python
import random
n= random.randrange(38)
if n == 0:
print '0', 'green'
elif n == 37:
print  '00', 'green'
elif n in ( 1,3,5,7,9, 12,14,16,18, 19,21,23,25,27, 30,32,34,36 ):
print n, 'red'
else:
print n, 'black'

1. We import random.
2. We create a random number, n in the range 0 to 37.
3. We check for 0 and 37 as special cases of single and double zero.
4. If the number is in the tuple of red spaces on the roulette layout, this is printed.
5. If none of the other rules are true, the number is in one of the black spaces.

## Tuple Statements¶

There are a number of statements that have specific features related to tuple objects.

The Assignment Statement. There is a variation on the assignment statement called a multiple-assignment statement that works nicely with tuples. We looked at this in Multiple Assignment Statement. Multiple variables are set by decomposing the items in the tuple.

For example:

>>> x, y = (1, 2)
>>> x
1
>>> y
2


An essential ingredient here is that a tuple has a fixed and known number of elements. For example a 2-dimensional geometric point might have a tuple with x and y. A 3-dimensional point might be a tuple with x, y, and z.

This works well because the right side of the assignment statement is fully evaluated before the assignments are performed. This allows things like swapping the values in two variables with x,y=y,x.

The for Statement. The for statement will step though all elements of a sequence.

For example:

s= 0
for i in ( 1,3,5,7,9, 12,14,16,18, 19,21,23,25,27, 30,32,34,36 ):
s += i
print "total",s


This will step through each number in the given tuple.

There are three built-in functions that will transform a tuple into another sequence. The enumerate(), sorted() and reversed() functions will provide the items of the tuple with their index, in sorted order or in reverse order.

## Tuple Built-in Functions¶

The tuple() function creates a tuple out of another sequence object.

tuple(sequence) → tuple
Create a tuple from another sequence. This will convert list or str to a tuple.

Functions which apply to tuples, but are defined elsewhere.

• len(). For tuples, this function returns the number of items.

>>> len( (1,1,2,3) )
4
>>> len( () )
0

• max(). For tuples, this function returns the maximum item.

>>> max( (1,9973,2) )
9973

• min(). For tuples, this function returns the minimum item.

• sum(). For tuples, this function sums the individual items.

>>> sum( (1,9973,2) )
9976

• any(). For tuples, Return True if there exists any item which is True.

>>> any( (0,None,False) )
False
>>> any( (0,None,False,42) )
True
>>> any( (1,True) )
True

• all(). For tuples, Return True if all items are True.

>>> all( (0,None,False,42) )
False
>>> all( (1,True) )
True

• enumerate(). Iterate through the tuple returning 2-tuples of ( index, item ).

In effect, this function “enumerates” all the items in a sequence: it provides a number and each element of the original sequence in a 2-tuple.

for i, x in someTuple:
print "position", i, " has value ", x


Consider the following.

>>> a = ( 3.1415926, "Words", (2+3j) )
>>> tuple( enumerate( a ) )
((0, 3.1415926000000001), (1, 'Words'), (2, (2+3j)))


We created a tuple from the enumeration. This shows that each item of the enumeration is a 2-tuple with the index number and an item from the original tuple.

• sorted(). Iterate through the tuple in sorted order.

>>> tuple( sorted( (9,1,8,2,7,3) ))
(1, 2, 3, 7, 8, 9)
>>> tuple( sorted( (9,1,8,2,7,3), reverse=True ))
(9, 8, 7, 3, 2, 1)

• reversed(). Iterate through the tuple in reverse order.

>>> tuple( reversed( (9,1,8,2,7,3) ) )
(3, 7, 2, 8, 1, 9)


The following function returns a tuple.

divmod(x, y ) -> ( div, mod)

Return a 2-tuple with ((x-x%y)/y, x%y). The return values have the invariant: . This is the quotient and the remainder in division.

The divmod() functions is often combined with multiple assignment. For example:

>>> q,r = divmod(355,113)
>>> q
3
>>> r
16
>>> q*113+r
355


## Tuple Exercises¶

These exercises implement some basic statistical algorithms. For some background on the Sigma operator, , see Digression on The Sigma Operator.

1. Blocks of Stock. A block of stock as a number of attributes, including a purchase date, a purchase price, a number of shares, and a ticker symbol. We can record these pieces of information in a tuple for each block of stock and do a number of simple operations on the blocks.

Let’s dream that we have the following portfolio.

 Purchase Date Purchase Price Shares Symbol :Current Price” 25 Jan 2001 43.50 25 CAT 92.45 25 Jan 2001 42.80 50 DD 51.19 25 Jan 2001 42.10 75 EK 34.87 25 Jan 2001 37.58 100 GM 37.58

We can represent each block of stock as a 5-tuple with purchase date, purchase price, shares, ticker symbol and current price.

portfolio= [ ( "25-Jan-2001", 43.50, 25, 'CAT', 92.45 ),
( "25-Jan-2001", 42.80, 50, 'DD', 51.19 ),
( "25-Jan-2001", 42.10, 75, 'EK', 34.87 ),
( "25-Jan-2001", 37.58, 100, 'GM', 37.58 )
]


Develop a function that examines each block, multiplies shares by purchase price and determines the total purchase price of the portfolio.

Develop a second function that examines each block, multiplies shares by purchase price and shares by current price to determine the total amount gained or lost.

2. Mean. Computing the mean of a list of values is relatively simple. The mean is the sum of the values divided by the number of values in the list . Since the statistical formula is so closely related to the actual loop, we’ll provide the formula, followed by an overview of the code.

[The cryptic-looking is a short-hand for “mean of variable x”.]

The definition of the mathematical operator leads us to the following method for computing the mean:

Computing Mean

1. Initialize. Set sum, s, to zero

2. Reduce. For each value, i, in the range 0 to the number of values in the list, n:

Set .

3. Result. Return .

3. Standard Deviation. The standard deviation can be done a few ways, but we’ll use the formula shown below. This computes a deviation measurement as the square of the difference between each sample and the mean. The sum of these measurements is then divided by the number of values times the number of degrees of freedom to get a standardized deviation measurement. Again, the formula summarizes the loop, so we’ll show the formula followed by an overview of the code.

[The cryptic-looking is short-hand for “standard deviation of variable x”.]

The definition of the mathematical operator leads us to the following method for computing the standard deviation:

Computing Standard Deviation

1. Initialize. Compute the mean, m.

Initialize sum, s, to zero.

2. Reduce. For each value, in the list:

Compute the difference from the mean, .

Set .

3. Variance. Compute the variance as . The . factor reflects the statistical notion of “degrees of freedom”, which is beyond the scope of this book.

4. Standard Deviation. Return the square root of the variance.

The math module contains the math.sqrt() funtion. For some additional information, see The math Module.

## Digression on The Sigma Operator¶

For those programmers new to statistics, this section provides background on the Sigma operator, .

The usual presentation of the summation operator looks like this.

The operator has three parts to it. Below it is a bound variable, i and the starting value for the range, written as . Above it is the ending value for the range, usually something like n. To the right is some function to execute for each value of the bound variable. In this case, a generic function, . This is read as “sum f ( i ) for i in the range 1 to n“.

This common definition of uses a closed range; one that includes the end values of 1 and n. This, however, is not a helpful definition for software. It is slightly simpler to define to start with zero and use a half-open interval. It still exactly n elements, including 0 and n-1; mathematically, .

For software design purposes, we prefer the following notation, but it is not often used. Since most statistical and mathematical texts use 1-based indexing, some care is required when translating formulae to programming languages that use 0-based indexing.

This shows the bound variable (i) and the range below the operator. It shows the function to execute on the right of the operator.

Statistical Algorithms. Our two statistical algorithms have a form more like the following. In this we are applying some function, f, to each value, of an array.

When computing the mean, there the function applied to each value does nothing. When computing standard deviation, the function applied involves subtracting and multiplying.

We can transform this definition directly into a for loop that sets the bound variable to all of the values in the range, and does some processing on each value of the sequence of values.

This is the Python implemention of . This computes two values, the sum, sum, and the number of elements, n .

Python Sigma Iteration

sum= 0
for x_i in aSequence:
fx_i = some processing of x_i
sum += fx_i
n= len(aSequence)
1. Execute the body of the loop for all values of x_i in the sequence aSequence. The sequence can be a tuple, list or other sequential container.
2. For simple mean calculation, the fx_i statement does nothing. For standard deviation, however, this statement computes the measure of deviation from the average.
3. We sum the x_i values for a mean calculation. We sum fx_i values for a standard deviation calculation.