Learn to Program Using Python: Indirection
You may find it useful to open another copy of this lesson in a separate browser window. That will make it easier for you to scroll back and forth among the different figures and listings, without losing your place, while you are reading about them.
Something for everyone
Beginners start at the beginning, and experienced programmers jump in further along. Learn to Program using Python: Lesson 1, Getting Started provides an overall description of this online programming course. (You will find a consolidated index to all of my Python, Java, and XML tutorials on my website.)
Previous lessons have illustrated
- How to create (pack) a tuple.
- How to access a tuple item using indexing.
- How to slice a tuple.
- How to nest tuples.
- How to create empty tuples.
- How to create single-item tuples.
- How to unpack a tuple
- How to use a numeric index to access the items in nested tuples.
- How to combine indexing and slicing to access groups of items in nested tuples.
This lesson will teach you how to use indirection to modify the value of an object referred to by a tuple item.
Look in the mailbox
Indirection works something like a party game that I recall from my childhood.
An adult would tell the children to go look in the mailbox. When they did, they would find a note telling them to go look in the kitchen cabinet. There they would find a note telling them to go look under the bed. This process might continue through several more notes until finally they would find a note telling them to look on the back porch. There they would find a box full of goodies.
Modern languages use indirection
Most modern programming languages make use of indirection in some form or another, and Python is no exception. Figure 1 contains a Python code fragment that illustrates the children's game mentioned above:
underTheBed = "Back Porch" kitchenCabinet = underTheBed mailbox = kitchenCabinet print mailbox
Figure 1 The Children's Game
In this simple example, the variable (area of memory) known as mailbox contains a reference or pointer to the variable known as kitchenCabinet.
The variable known as kitchenCabinet contains a reference or pointer to the variable known as underTheBed.
The variable known as underTheBed contains a reference to a string object, which in turn identifies the Back Porch as the end of the path.
Traversing the path
Fortunately, unlike children playing the party game, Python programmers are not required to traverse the path one step at a time. In this example, the print statement shown in the last line will cause the entire path to be traversed and the printed output will be:
Why is this called indirection?
This process is called indirection because the final objective is attained through an indirect path rather than a direct path.
Listing 9, near the end of the lesson, shows a Python script that:
- Creates and displays a simple list containing three integer values.
- Modifies the value stored at index value 1 in the list and displays the modified list.
- Creates and displays a simple tuple containing the list.
- Modifies a value stored in the list, which is referred to by an item in the tuple.
- Displays the tuple with the modified list value.
- Attempts unsuccessfully to modify the value of an item in the tuple
The important point here is that while the program is able to indirectly modify a value stored in a mutable list referred to by an item in the tuple, it is unable to directly modify the value of an item in the tuple.
A list is a mutable sequence.
A tuple is an immutable sequence.
Now I will break this program down and discuss it in fragments.
The original list object
Listing 1 shows the code that creates and displays the list, directly modifies a value in the list, and then displays the modified list.
# File Tuple07.py #------------------------------- # Create a list L1 = [1,2,3] print "Original list" print L1 # Modify the list L1 = "a" print "Modified list" print L1 Listing 1
This code was included primarily to illustrate what I mean by directly modifying a list (or tuple) item.
The boldface statement in Listing 1 modifies the value of the list item whose index value is 1. In this case, the value of the list item is modified from an integer value of 2 to a reference to a string object containing the letter a.
We will see later that because a tuple is immutable, a similar statement cannot be successfully applied to a tuple.
Let's see some output
Listing 2 shows the output produced by the code fragment in Listing 1. As expected from the above explanation, the modified list is different from the original list.
Original list [1, 2, 3] Modified list [1, 'a', 3] Listing 2
Put the list in a tuple
Listing 3 shows code that creates a tuple containing the list. Actually, the tuple probably doesn't physically contain the list, although we often speak of it that way. Rather, the tuple probably contains an item that refers to the list.
# Create a simple tuple # containing the list t1 = "a",L1,"c" print "Tuple containing list" print t1 Listing 3
Do we really care?
As high-level Python programmers, we don't need to be too concerned with the physical implementation. Rather, we need to be concerned with the functional behavior.
Later, I will use the item that refers to the list to indirectly modify the value of one of the items in the list.
The output produced by the code in Listing 3 is shown in Listing 4. As you can see, the print statement traverses the path and shows us the contents of the list as though it is physically embedded in the tuple.
Tuple containing list ('a', [1, 'a', 3], 'c') Listing 4
The main point of the lesson
Listing 5 shows a boldface statement that:
- Gains access to the tuple item at index value 1, which is a reference to the list.
- Uses that reference to gain access to and modify the value of the list item at index value 1.
# "Modify list value" t1 = "X" print "Modified stored value" print t1 Listing 5
What does this really mean?
You might interpret the behavior of this statement as follows:
- Go to index value 1 of the tuple, where you will find a reference to a list.
- Go to the list referred to by the tuple item and store a new value in the list item at index value 1.
Let's see the output
Listing 6 shows the output from the code fragment in Listing 5 with the list item whose value was modified highlighted in boldface.
Modified stored value ('a', [1, 'X', 3], 'c') Listing 6
The list item was changed from a reference to a string containing a lower-case a to a reference to a string containing an upper-case X.
Try to modify a tuple item
Just for fun, let's see what happens if we attempt to modify the value of an item in the tuple. The code to do this is shown in Listing 7.
print "Modify the tuple" t1 = "A" Listing 7
We already know that because the tuple item is immutable, its value cannot be modified. Therefore, the error shown in Listing 8 is produced.
Modify the tuple Traceback (innermost last): File "tuple07.py", line 28, in ? t1 = "A" TypeError: object doesn't support item assignment Listing 8 (Line breaks manually inserted)
Ans: This is a trick question. It cannot be done because, as explained in an earlier lesson entitled
Learn to Program using Python: Strings, Part II
, a string object is an immutable sequence. This is illustrated by the code in Listing 10.
# File Tuple24.py # Rev 08/02/00 # Copyright 2000, R. G. Baldwin # Illustrates attempt to # modify char in string # referred to by item # in tuple. #------------------------------- t1 =(1,2,"abc") print t1 t1 ="Z" print t1 Listing 10
Listing 10, which produces the error message shown in Listing 11.
(1, 2, 'abc') Traceback (innermost last): File "tuple24.py", line 11, in ? t1 ="Z" TypeError: object doesn't support item assignment Listing 11 (Line breaks manually inserted)
# File Tuple07.py # Rev 8/5/00 # Copyright 2000, R. G. Baldwin # Illustrates modifying value # stored in an object referred # to by a tuple item. #------------------------------- # Create a list L1 = [1,2,3] print "Original list" print L1 # Modify the list L1 = "a" print "Modified list" print L1 # Create a simple tuple # containing the list t1 = "a",L1,"c" print "Tuple containing list" print t1 # "Modify list value" L1 = "X" print "Modified stored value" print t1 print "Modify the tuple" t1 = "A" Listing 9
Copyright 2000, Richard G. Baldwin. Reproduction in whole or in part in any form or medium without express written permission from Richard Baldwin is prohibited.
About the authorRichard Baldwin is a college professor and private consultant whose primary focus is a combination of Java and XML. In addition to the many platform-independent benefits of Java applications, he believes that a combination of Java and XML will become the primary driving force in the delivery of structured information on the Web.
Richard has participated in numerous consulting projects involving Java, XML, or a combination of the two. He frequently provides onsite Java and/or XML training at the high-tech companies located in and around Austin, Texas. He is the author of Baldwin's Java Programming Tutorials, which has gained a worldwide following among experienced and aspiring Java programmers. He has also published articles on Java Programming in Java Pro magazine.
Richard holds an MSEE degree from Southern Methodist University and has many years of experience in the application of computer technology to real-world problems.