Storing Data Using Tuples

Lists aren’t the only kind of ordered sequence in Python. You’ve already learned about one of the others: strings (see Chapter 4, Working with Text). Formally, a string is an immutable sequence of characters. The characters in a string are ordered and a string can be indexed and sliced like a list to create new strings:

 >>>​​ ​​rock​​ ​​=​​ ​​'anthracite'
 >>>​​ ​​rock[9]
 'e'
 >>>​​ ​​rock[0:3]
 'ant'
 >>>​​ ​​rock[-5:]
 'acite'
 >>>​​ ​​for​​ ​​character​​ ​​in​​ ​​rock[:5]:
 ...​​ ​​print(character)
 ...
 
 a
 n
 t
 h
 r

Python also has an immutable sequence type called a tuple. Tuples are written using parentheses instead of brackets; like strings and lists, they can be subscripted, sliced, and looped over:

 >>>​​ ​​bases​​ ​​=​​ ​​(​​'A'​​,​​ ​​'C'​​,​​ ​​'G'​​,​​ ​​'T'​​)
 >>>​​ ​​for​​ ​​base​​ ​​in​​ ​​bases:
 ...​​ ​​print(base)
 ...
 A
 C
 G
 T

There’s one small catch: although () represents the empty tuple, a tuple with one element is not written as (x) but as (x,) (with a trailing comma). This is done to avoid ambiguity. If the trailing comma weren’t required, (5 + 3) could mean either 8 (under the normal rules of arithmetic) or the tuple containing only the value 8:

 >>>​​ ​​(8)
 8
 >>>​​ ​​type((8))
 <class 'int'>
 >>>​​ ​​(8,)
 (8,)
 >>>​​ ​​type((8,))
 <class 'tuple'>
 >>>​​ ​​(5​​ ​​+​​ ​​3)
 8
 >>>​​ ​​(5​​ ​​+​​ ​​3,)
 (8,)

Unlike lists, once a tuple is created, it cannot be mutated:

 >>>​​ ​​life​​ ​​=​​ ​​([​​'Canada'​​,​​ ​​76.5],​​ ​​[​​'United States'​​,​​ ​​75.5],​​ ​​[​​'Mexico'​​,​​ ​​72.0])
 >>>​​ ​​life[0]​​ ​​=​​ ​​life[1]
 Traceback (most recent call last):
  File "<stdin>", line 1, in ?
 TypeError: object does not support item assignment

However, the objects inside tuples can still be mutated:

 >>>​​ ​​life​​ ​​=​​ ​​([​​'Canada'​​,​​ ​​76.5],​​ ​​[​​'United States'​​,​​ ​​75.5],​​ ​​[​​'Mexico'​​,​​ ​​72.0])
 >>>​​ ​​life[0][1]​​ ​​=​​ ​​80.0
 >>>​​ ​​life
 (['Canada', 80.0], ['United States', 75.5], ['Mexico', 72.0])

Here is an example that explores what is mutable and what isn’t. We’ll build the same tuple as in the previous example, but we’ll do it in steps. First let’s create three lists:

 >>>​​ ​​canada​​ ​​=​​ ​​[​​'Canada'​​,​​ ​​76.5]
 >>>​​ ​​usa​​ ​​=​​ ​​[​​'United States'​​,​​ ​​75.5]
 >>>​​ ​​mexico​​ ​​=​​ ​​[​​'Mexico'​​,​​ ​​72.0]

That builds this memory model:

images/setdict/mutable1.png

We’ll create a tuple using those variables:

 >>>​​ ​​life​​ ​​=​​ ​​(canada,​​ ​​usa,​​ ​​mexico)
images/setdict/mutable2.png

Notice that none of the four variables know about the others, and that the tuple object contains three references, one for each of the country lists.

Now let’s change what variable mexico refers to:

 >>>​​ ​​mexico​​ ​​=​​ ​​[​​'Mexico'​​,​​ ​​72.5]
 >>>​​ ​​life
 (['Canada', 76.5], ['United States', 75.5], ['Mexico', 72.0])

Notice that the tuple that variable life refers to hasn’t changed. Here’s the new picture as shown.

images/setdict/mutable3.png

life[0] will always refer to the same list object—we can’t change the memory address stored in life[0]—but we can mutate that list object. And because variable canada also refers to that list, it sees the mutation:

 >>>​​ ​​life[0][1]​​ ​​=​​ ​​80.0
 >>>​​ ​​canada
 ['Canada', 80.0]
images/setdict/mutable4.png

We hope that it is clear how essential it is to thoroughly understand variables and references and how collections contain references to objects and not to variables.

Assigning to Multiple Variables Using Tuples

You can assign to multiple variables in the same assignment statement:

 >>>​​ ​​(x,​​ ​​y)​​ ​​=​​ ​​(10,​​ ​​20)
 >>>​​ ​​x
 10
 >>>​​ ​​y
 20

As with a normal assignment statement (see Assignment Statement), Python first evaluates all expressions on the right side of the = symbol, and then it assigns those values to the variables on the left side.

Python uses the comma as a tuple constructor, so we can leave off the parentheses:

 >>>​​ ​​10,​​ ​​20
 (10, 20)
 >>>​​ ​​x,​​ ​​y​​ ​​=​​ ​​10,​​ ​​20
 >>>​​ ​​x
 10
 >>>​​ ​​y
 20

In fact, multiple assignment will work with lists and sets as well. Python will happily pull apart information out of any collection:

 >>>​​ ​​[[w,​​ ​​x],​​ ​​[[y],​​ ​​z]]​​ ​​=​​ ​​[{10,​​ ​​20},​​ ​​[(30,),​​ ​​40]]
 >>>​​ ​​w
 10
 >>>​​ ​​x
 20
 >>>​​ ​​y
 30
 >>>​​ ​​z
 40

Any depth of nesting will work as long as the structure on the right can be translated into the structure on the left.

One of the most common uses of multiple assignment is to swap the values of two variables:

 >>>​​ ​​s1​​ ​​=​​ ​​'first'
 >>>​​ ​​s2​​ ​​=​​ ​​'second'
 >>>​​ ​​s1,​​ ​​s2​​ ​​=​​ ​​s2,​​ ​​s1
 >>>​​ ​​s1
 'second'
 >>>​​ ​​s2
 'first'

This works because the expressions on the right side of the operator = are evaluated before assigning to the variables on the left side.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.226.185.196