Learning Python - Mark Lutz [587]
>>>
>>> spam
Traceback (most recent call last):
File " NameError: name 'spam' is not defined Breaks and cycles. When you type this code:L = [1, 2] L.append(L) you create a cyclic data structure in Python. In Python releases before 1.5.1, the Python printer wasn’t smart enough to detect cycles in objects, and it would print an unending stream of [1, 2, [1, 2, [1, 2, [1, 2, and so on, until you hit the break-key combination on your machine (which, technically, raises a keyboard-interrupt exception that prints a default message). Beginning with Python 1.5.1, the printer is clever enough to detect cycles and prints [[...]] instead to let you know that it has detected a loop in the object’s structure and avoided getting stuck printing forever. The reason for the cycle is subtle and requires information you will glean in Part II, so this is something of a preview. But in short, assignments in Python always generate references to objects, not copies of them. You can think of objects as chunks of memory and of references as implicitly followed pointers. When you run the first assignment above, the name L becomes a named reference to a two-item list object—a pointer to a piece of memory. Python lists are really arrays of object references, with an append method that changes the array in-place by tacking on another object reference at the end. Here, the append call adds a reference to the front of L at the end of L, which leads to the cycle illustrated in Figure B-1: a pointer at the end of the list that points back to the front of the list. Besides being printed specially, as you’ll learn in Chapter 6 cyclic objects must also be handled specially by Python’s garbage collector, or their space will remain unreclaimed even when they are no longer in use. Though rare in practice, in some programs that traverse arbitrary objects or structures you might have to detect such cycles yourself by keeping track of where you’ve been to avoid looping. Believe it or not, cyclic data structures can sometimes be useful, despite their special-case printing. Figure B-1. A cyclic object, created by appending a list to itself. By default, Python appends a reference to the original list, not a copy of the list. Part II, Types and Operations See Test Your Knowledge: Part II Exercises in Chapter 9 for the exercises. The basics. Here are the sorts of results you should get, along with a few comments about their meaning. Again, note that ; is used in a few of these to squeeze more than one statement onto a single line (the ; is a statement separator), and commas build up tuples displayed in parentheses. Also keep in mind that the / division result near the top differs in Python 2.6 and 3.0 (see Chapter 5 for details), and the list wrapper around dictionary method calls is needed to display results in 3.0, but not 2.6 (see Chapter 8):# Numbers >>> 2 ** 16 # 2 raised to the power 16 65536 >>> 2 / 5, 2 / 5.0 # Integer / truncates in 2.6, but not 3.0 (0.40000000000000002, 0.40000000000000002) # Strings >>> "spam" + "eggs" # Concatenation 'spameggs' >>> S = "ham" >>> "eggs " + S 'eggs ham' >>> S * 5 # Repetition 'hamhamhamhamham' >>> S[:0] # An empty slice at the front -- [0:0] '' # Empty of same type as object sliced >>> "green %s and %s" % ("eggs", S) # Formatting 'green eggs and ham' >>> 'green {0} and {1}'.format('eggs', S) 'green eggs and ham' # Tuples >>> ('x',)[0] # Indexing a single-item tuple 'x' >>> ('x', 'y')[1] # Indexing a 2-item tuple 'y' # Lists >>> L = [1,2,3] + [4,5,6] # List operations >>> L, L[:], L[:0], L[-2], L[-2:] ([1, 2, 3, 4, 5, 6], [1, 2, 3, 4, 5, 6], [], 5, [5, 6]) >>> ([1,2,3]+[4,5,6])[2:4] [3, 4] >>> [L[2], L[3]] # Fetch from offsets; store in a list [3, 4] >>> L.reverse(); L # Method: reverse list in-place [6, 5, 4, 3, 2, 1] >>> L.sort(); L # Method: sort list in-place [1, 2, 3, 4, 5, 6] >>> L.index(4) # Method: offset of first 4 (search) 3 # Dictionaries >>> {'a':1, 'b':2}['b'] #