- Python Shortcuts, Commands, and Packages
- 4.2 Twenty-Two Programming Shortcuts
- 4.3 Running Python from the Command Line
- 4.4 Writing and Using Doc Strings
- 4.5 Importing Packages
- 4.6 A Guided Tour of Python Packages
- 4.7傅nctions as First-Class Objects
- 4.8 Variable-Length Argument Lists
- 4.9 Decorators and Function Profilers
- 4.10 Generators
- 4.11 Accessing Command-Line Arguments
- Chapter 4 Summary
- Chapter 4 Questions for Review
- Chapter 4 Suggested Problems
4.2 Twenty-Two Programming Shortcuts
This section lists the most common techniques for shortening and tightening your Python code. Most of these are new in the book, although a few of them have been introduced before and are presented in greater depth here.
Use Python line continuation as needed.
Useforloops intelligently.
Understand combined operator assignment (+= etc.).
Use multiple assignment.
Use tuple assignment.
Use advanced tuple assignment.
Use list and string “multiplication.”
Return multiple values.
Use loops and theelsekeyword.
Take advantage of Booleans andnot.
Treat strings as lists of characters.
Eliminate characters by usingreplace.
Don’t write unnecessary loops.
Use chained comparisons.
Simulate “switch” with a table of functions.
Use theisoperator correctly.
Use one-lineforloops.
Squeeze multiple statements onto a line.
Write one-line if/then/else statements.
Create Enum values withrange.
Reduce the inefficiency of theprintfunction within IDLE.
Place underscores inside large numbers.
Let’s look at these ideas in detail.
4.2.1 Use Python Line Continuation as Needed
In Python, the normal statement terminator is just the end of a physical line (although note the exceptions in Section 3.18). This makes programming easier, because you can naturally assume that statements are one per line.
But what if you need to write a statement longer than one physical line? This dilemma can crop up in a number of ways. For example, you might have a string to print that you can’t fit on one line. You could use literal quotations, but line wraps, in that case, are translated as newlines—something you might not want. The solution, first of all, is to recognize that literal strings positioned next to other literal strings are automatically concatenated.
>>>my_str = 'I am Hen-er-y the Eighth,' ' I am!'>>>print(my_str)I am Hen-er-y the Eighth, I am!
If these substrings are too long to put on a single physical line, you have a couple of choices. One is to use the line-continuation character, which is a backslash (\).
my_str = 'I am Hen-er-y the Eighth,' ' I am!'
Another technique is to observe that any open—and so far unmatched—parenthesis, square bracket, or brace automatically causes continuation onto the next physical line. Consequently, you can enter as long a statement as you want—and you can enter a string of any length you want—without necessarily inserting newlines.
my_str = ('I am Hen-er-y the Eighth, ' 'I am! I am not just any Henry VIII, ' 'I really am!')
This statement places all this text in one string. You can likewise use open parentheses with other kinds of statements.
length_of_hypotenuse = ( (side1 * side1 + side2 * side2) ** 0.5 )
A statement is not considered complete until all open parentheses [(] have been matched by closing parentheses [)]. The same is true for braces and square brackets. As a result, this statement will automatically continue to the next physical line.
4.2.2 Use “for” Loops Intelligently
If you come from the C/C++ world, you may tend to overuse therangefunction to print members of a list. Here’s an example of the C way of writing aforloop, usingrangeand an indexing operation.
beat_list = ['John', 'Paul', 'George', 'Ringo'] for i in range(len(beat_list)): print(beat_list[i])
If you ever write code like this, you should try to break the habit as soon as you can. It’s better to print the contents of a list or iterator directly.
beat_list = ['John', 'Paul', 'George', 'Ringo'] for guy in beat_list: print(guy)
Even if you need access to a loop variable, it’s better to use theenumeratefunction to generate such numbers. Here’s an example:
beat_list = ['John', 'Paul', 'George', 'Ringo'] for i, name in enumerate(beat_list, 1): print(i, '. ', name, sep='')
This prints
1. John 2. Paul 3. George 4. Ringo
There are, of course, some cases in which it’s necessary to use indexing. That happens most often when you are trying to change the contents of a list in place.
4.2.3 Understand Combined Operator Assignment (+= etc.)
The combined operator-assignment operators are introduced in Chapter 1 and so are reviewed only briefly here. Remember that assignment (=) can be combined with any of the following operators:+,-,/,//,%,**,&,^,|,<<,>>.
The operators&,|, and^are bitwise “and,” “or,” and “exclusive or,” respectively. The operators<<and>>perform bit shifts to the left and to the right.
This section covers some finer points of operator-assignment usage. First, any assignment operator has low precedence and is carried out last.
Second, an assignment operator may or may not be in place, depending on whether the type operated on is mutable.In placerefers to operations that work on existing data in memory rather than creating a completely new object. Such operations are faster and more efficient.
Integers, floating-point numbers, and strings are immutable. Assignment operators, used with these types, do not cause in-place assignment; they instead must produce a completely new object, which is reassigned to the variable. Here’s an example:
s1 = s2 = 'A string.' s1 += '...with more stuff!' print('s1:', s1) print('s2:', s2)
Theprintfunction, in this case, produces the following output:
s1: A string...with more stuff! s2: A string.
Whens1was assigned a new value, it did not change the string data in place; it assigned a whole new string tos1. Buts2is a name that still refers to the original string data. This is whys1ands2now contain different strings.
But lists are mutable, and therefore changes to lists can occur in place.
a_list = b_list = [10, 20] a_list += [30, 40] print('a_list:', a_list) print('b_list:', b_list)
This code prints
a_list: [10, 20, 30, 40] b_list: [10, 20, 30, 40]
In this case, the change was made to the list in place, so there was no need to create a new list and reassign that list to the variable. Therefore,a_listwas not assigned to a new list, andb_list, a variable that refers to the same data in memory, reflects the change as well.
就地操作几乎总是更高效nt. In the case of lists, Python reserves some extra space to grow when allocating a list in memory, and that in turns permitsappendoperations, as well as+=, to efficiently grow lists. However, occasionally lists exceed the reserved space and must be moved. Such memory management is seamless and has little or no impact on program behavior.
Non-in-place operations are less efficient, because a new object must be created. That’s why it’s advisable to use thejoinmethod to grow large strings rather than use the+=operator, especially if performance is important. Here’s an example using thejoinmethod to create a list and join 26 characters together.
str_list = [] n = ord('a') for i in range(n, n + 26): str_list += chr(i) alphabet_str = ''.join(str_list)
Figures 4.1and4.2illustrate the difference between in-place operations and non-in-place operations. InFigure 4.1, string data seems to be appended onto an existing string, but what the operation really does is to create a new string and then assign it to the variable—which now refers to a different place in memory.
Figure 4.1.Appending to a string (not in-place)
But inFigure 4.2,列表数据附加到一个现有的列表out the need to create a new list and reassign the variable.
Figure 4.2.Appending to a list (in-place)
Here’s a summary:
Combined assignment operators such as+=cause in-place changes to data if the object is mutable (such as a list); otherwise, a whole new object is assigned to the variable on the left.
In-place operations are faster and use space more efficiently, because they do not force creation of a new object. In the case of lists, Python usually allocates extra space so that the list can be grown more efficiently at run time.
4.2.4 Use Multiple Assignment
Multiple assignment is one of the most commonly used coding shortcuts in Python. You can, for example, create five different variables at once, assigning them all the same value—in this case, 0:
a = b = c = d = e = 0
Consequently, the following returnsTrue:
a is b
This statement would no longer returnTrueif either of these variables was later assigned to a different object.
Even though this coding technique may look like it is borrowed from C and C++, you should not assume that Python follows C syntax in most respects. Assignment in Python is a statement and not an expression, as it is in C.
4.2.5 Use Tuple Assignment
Multiple assignment is useful when you want to assign a group of variables the same initial value.
But what if you want to assign different values to different variables? For example, suppose you want to assign 1 to a, and 0 to b. The obvious way to do that is to use the following statements:
a = 1 b = 0
But throughtuple assignment,you can combine these into a single statement.
a, b = 1, 0
In this form of assignment, you have a series of values on one side of the equals sign (=) and another on the right. They must match in number, with one exception: You can assign a tuple of any size to a single variable (which itself now represents a tuple as a result of this operation).
a = 4, 8, 12 # a is now a tuple containing three values.
Tuple assignment can be used to write some passages of code more compactly. Consider how compact a Fibonacci-generating function can be in Python.
def fibo(n): a, b = 1, 0 while a <= n: print(a, end=' ') a, b = a + b, a
In the last statement, the variableagets a new value:a + b; the variablebgets a new value—namely, the old value ofa.
Most programming languages have no way to setaandbsimultaneously. Setting the value ofachanges what gets put intob, and vice versa. So normally, a temporary variable would be required. You could do that in Python, if you wanted to:
temp = a # Preserve old value of a a = a + b # Set new value of a b = temp # Set b to old value of a
But with tuple assignment, there’s no need for a temporary variable.
a, b = a + b, a
Here’s an even simpler example of tuple assignment. Sometimes, it’s useful to swap two values.
x, y = 1, 25 print(x, y) # prints 1 25 x, y = y, x print(x, y) # prints 25 1
The interesting part of this example is the statement that performs the swap:
x, y = y, x
In another language, such an action would require three separate statements. But Python does not require this, because—as just shown—it can do the swap all at once. Here is what another language would require you to do:
temp = x x = y y = temp
4.2.6 Use Advanced Tuple Assignment
Tuple assignment has some refined features. For example, you can unpack a tuple to assign to multiple variables, as in the following example.
tup = 10, 20, 30 a, b, c = tup print(a, b, c) # Produces 10, 20, 30
It’s important that the number of input variables on the left matches the size of the tuple on the right. The following statement would produce a runtime error.
tup = 10, 20, 30 a, b = tup # Error: too many values to unpack
Another technique that’s occasionally useful is creating a tuple that has one element. That would be easy to do with lists.
my_list = [3]
This is a list with one element, 3. But the same approach won’t work with tuples.
my_tup = (3) print(type(my_tup))
Thisprintstatement shows thatmy_tup, in this case, produced a simple integer.
This is not what was wanted in this case. The parentheses were treated as a no-op, as would any number of enclosing parentheses. But the following statement produces a tuple with one element, although, to be fair, a tuple with just one element isn’t used very often.
my_tup = (3,) # Assign tuple with one member, 3.
The use of an asterisk (*) provides a good deal of additional flexibility with tuple assignment. You can use it to split off parts of a tuple and have one (and only one) variable that becomes the default target for the remaining elements, which are then put into a list. Some examples should make this clear.
a, *b = 2, 4, 6, 8
In this example,a得到的值2,bis assigned to a list:
2 [4, 6, 8]
You can place the asterisk next to any variable on the left, but in no case more than one. The variable modified with the asterisk is assigned a list of whatever elements are left over. Here’s an example:
a, *b, c = 10, 20, 30, 40, 50
In this case,aandcrefer to 10 and 50, respectively, after this statement is executed, andbis assigned the list[20, 30, 40].
You can, of course, place the asterisk next to a variable at the end.
big, bigger, *many = 100, 200, 300, 400, 500, 600
Printing these variables produces the following:
>>>print(big, bigger, many, sep='\n')100 200 [300, 400, 500, 600]
4.2.7 Use List and String “Multiplication”
Serious programs often deal with large data sets—for example, a collection of 10,000 integers all initialized to 0. In languages such as C and Java, the way to do this is to first declare an array with a large dimension.
Because there are no data declarations in Python, the only way to create a large list is to construct it on the right side of an assignment. But constructing a super-long list by hand is impractical. Imagine trying to construct a super-long list this way:
my_list = [0, 0, 0, 0, 0, 0, 0, 0...]
As you can imagine, entering 10,000 zeros into program code would be very time-consuming! And it would make your hands ache.
Applying the multiplication operator provides a more practical solution:
my_list = [0] * 10000
This example creates a list of 10,000 integers, all initialized to 0.
Such operations are well optimized in Python, so that even in the interactive development environment (IDLE), such interactions are handled quickly.
>>>my_list = [0] * 10000>>>len(my_list)10000
Note that the integer may be either the left or the right operand in such an expression.
>>>my_list = 1999 * [12]>>>len(my_list)1999
You can also “multiply” longer lists. For example, the following list is 300 elements long. It consists of the numbers 1, 2, 3, repeated over and over.
>>>trip_list = [1, 2, 3] * 100>>>len(trip_list)300
The multiplication sign (*) does not work with dictionaries and sets, which require unique keys. But it does work with the string class (str); for example, you can create a string consisting of 40 underscores, which you might use for display purposes:
divider_str = '_' * 40
Printing out this string produces the following:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
4.2.8 Return Multiple Values
You can’t pass a simple variable to a Python function, change the value inside the function, and expect the original variable to reflect the change. Here’s an example:
def double_me(n): n *= 2 a = 10 double_me(a) print(a) # Value of a did not get doubled!!
Whennis assigned a new value, the association is broken between that variable and the value that was passed. In effect,nis a local variable that is now associated with a different place in memory. The variable passed to the function is unaffected.
But you can always use a return value this way:
def double_me (n):返回n * 2 = 10 = double_me(a) print(a)
因此,为了得到一个outparameter, just return a value. But what if you want more than one out parameter?
In Python, you can return as many values as you want. For example, the following function performs the quadratic equation by returning two values.
def quad(a, b, c): determin = (b * b - 4 * a * c) ** .5 x1 = (-b + determin) / (2 * a) x2 = (-b - determin) / (2 * a) return x1, x2
This function has three input arguments and two output variables. In calling the function, it’s important to receive both arguments:
x1, x2 = quad(1, -1, -1)
If you return multiple values to a single variable in this case, that variable will store the values as a tuple. Here’s an example:
>>>x = quad(1, -1, -1)>>>x(1.618033988749895, -0.6180339887498949)
Note that this feature—returning multiple values—is actually an application of the use of tuples in Python.
4.2.9 Use Loops and the “else” Keyword
Theelsekeyword is most frequently used in combination with theifkeyword. But in Python, it can also be used withtry-exceptsyntax and with loops.
With loops, theelseclause is executed if the loop has completed without an early exit, such asbreak. This feature applies to bothwhileloops andforloops.
The following example tries to find an even divisor ofn, up to and including the limit,max. If no such divisor is found, it reports that fact.
def find_divisor(n, max): for i in range(2, max + 1): if n % i == 0: print(i, 'divides evenly into', n) break else: print('No divisor found')
Here’s an example:
>>>find_divisor(49, 6)No divisor found >>>find_divisor(49, 7)7 divides evenly into 49
4.2.10 Take Advantage of Boolean Values and “not”
Every object in Python evaluates toTrueorFalse. For example, every empty collection in Python evaluates toFalseif tested as a Boolean value; so does the special valueNone. Here’s one way of testing a string for being length zero:
if len(my_str) == 0: break
However, you can instead test for an input string this way:
if not s: break
Here are the general guidelines for Boolean conversions.
Nonempty collections and nonempty strings evaluate asTrue; so do nonzero numeric values.
Zero-length collections and zero-length strings evaluate toFalse; so does any number equal to 0, as well as the special valueNone.
4.2.11 Treat Strings as Lists of Characters
When you’re doing complicated operations on individual characters and building a string, it’s sometimes more efficient to build a list of characters (each being a string of length 1) and use list comprehension plusjointo put it all together.
For example, to test whether a string is a palindrome, it’s useful to omit all punctuation and space characters and convert the rest of the string to either all-uppercase or all-lowercase. List comprehension does this efficiently.
test_str = input('Enter test string: ') a_list = [c.upper() for c in test_str if c.isalnum()] print(a_list == a_list[::-1])
The second line in this example uses list comprehension, which was introduced in Section 3.15, “List Comprehension.”
The third line in this example uses slicing to get the reverse of the list. Now we can test whethertest_stris a palindrome by comparing it to its own reverse. These three lines of code have to be the shortest possible program for testing whether a string is a palindrome. Talk about compaction!
Enter test string:A man, a plan, a canal, Panama!True
4.2.12 Eliminate Characters by Using “replace”
To quickly remove all instances of a particular character from a string, usereplaceand specify the empty string as the replacement.
For example, a code sample in Chapter 10 asks users to enter strings that represent fractions, such as “1/2”. But if the user puts extra spaces in, as in “1 / 2”, this could cause a problem. Here’s some code that takes an input string,s, and quickly rids it of all spaces wherever they are found (so it goes beyond stripping):
s = s.replace(' ', '')
Using similar code, you can quickly get rid of all offending characters or substrings in the same way—but only one at a time. Suppose, however, that you want to get rid of all vowels in one pass. List comprehension, in that case, comes to your aid.
a_list = [c for c in s if c not in 'aeiou'] s = ''.join(a_list)
4.2.13 Don’t Write Unnecessary Loops
Make sure that you don’t overlook all of Python’s built-in abilities, especially when you’re working with lists and strings. With most computer languages, you’d probably have to write a loop to get the sum of all the numbers in a list. But Python performs summation directly. For example, the following function calculates 1 + 2 + 3 … + N:
def calc_triangle_num(n): return sum(range(n+1))
Another way to use thesumfunction is to quickly get the average (the mean) of any list of numbers.
def get_avg(a_list): return sum(a_list) / len(a_list)
4.2.14 Use Chained Comparisons (n < x < m)
This is a slick little shortcut that can save you a bit of work now and then, as well as making your code more readable.
It’s common to writeifconditions such as the following:
if 0 < x and x < 100: print('x is in range.')
But in this case, you can save a few keystrokes by instead using this:
if 0 < x < 100: # Use 'chained' comparisons. print('x is in range.')
This ability potentially goes further. You can chain together any number of comparisons, and you can include any of the standard comparison operators, including==,<,<=,>, and>=. The arrows don’t even have to point in the same direction or even be combined in any order! So you can do things like this:
a, b, c = 5, 10, 15 if 0 < a <= c > b > 1: print('All these comparisons are true!') print('c is equal or greater than all the rest!')
You can even use this technique to test a series of variables for equality. Here’s an example:
a = b = c = d = e = 100 if a == b == c == d == e: print('All the variables are equal to each other.')
For larger data sets, there are ways to achieve these results more efficiently. Any list, no matter how large, can be tested to see whether all the elements are equal this way:
if min(a_list) == max(a_list): print('All the elements are equal to each other.')
However, when you just want to test a few variables for equality or perform a combination of comparisons on a single line, the techniques shown in this section are a nice convenience with Python. Yay, Python!
4.2.15 Simulate “switch” with a Table of Functions
This next technique is nice because it can potentially save a number of lines of code.
Section 15.12 offers the user a menu of choices, prompts for an integer, and then uses that integer to decide which of several functions to call. The obvious way to implement this logic is with a series ofif/elifstatements, because Python has no “switch” statement.
if n == 1: do_plot(stockdf) elif n == 2: do_highlow_plot(stockdf) elif n == 3: do_volume_subplot(stockdf) elif n == 4: do_movingavg_plot(stockdf)
Code like this is verbose. It will work, but it’s longer than it needs to be. But Python functions are objects, and they can be placed in a list just like any other kind of objects. You can therefore get a reference to one of the functions and call it.
fn = [do_plot, do_highlow_plot, do_volume_subplot, do_movingavg_plot][n-1] fn(stockdf) # Call the function
For example,n-1is evaluated, and if that value is 0 (that is,nis equal to 1), the first function listed,do_plot, is executed.
This code creates a compact version of a C++ switch statement by calling a different function depending on the value ofn. (By the way, the value 0 is excluded in this case, because that value is used to exit.)
You can create a more flexible control structure by using a dictionary combined with functions. For example, suppose that “load,” “save,” “update,” and “exit” are all menu functions. We might implement the equivalent of a switch statement this way:
menu_dict = {'load':load_fn, 'save':save_fn, 'exit':exit_fn, 'update':update_fn} (menu_dict[selector])() # Call the function
Now the appropriate function will be called, depending on the string contained inselector, which presumably contains'load','save','update', or'exit'.
4.2.16 Use the “is” Operator Correctly
Python supports both a test-for-equality operator (==) and anisoperator. These tests sometimes return the same result, and sometimes they don’t. If two strings have the same value, a test for equality always producesTrue.
a = 'cat' b = 'cat' a == b # This must produce True.
But theisoperator isn’t guaranteed to produceTruein string comparisons, and it’s risky to rely upon. A constructed string isn’t guaranteed to match another string if you useisrather than test-for-equality (==). For example:
>>>s1 = 'I am what I am and that is all that I am.'>>>s2 = 'I am what I am' + ' and that is all that I am.'>>>s1 == s2True >>>s1 is s2False
What this example demonstrates is that just because two strings have identical contents does not mean that they correspond to the same object in memory, and therefore theisoperator producesFalse.
If theisoperator is unreliable in such cases, why is it in the language at all? The answer is that Python has some unique objects, such asNone,True, andFalse. When you’re certain that you’re comparing a value to a unique object, then theiskeyword works reliably; moreover, it’s preferable in those situations because such a comparison is more efficient.
a_value = my_function() if a_value is None: # Take special action if None is returned.
4.2.17 Use One-Line “for” Loops
If aforloop is short enough, with only one statement inside the loop (that is, the statementbody), you can squeeze the entireforloop onto a single physical line.
forvarinsequence:statement
Not all programmers favor this programming style. However, it’s useful as a way of making your program more compact. For example, the following one-line statement prints all the numbers from 0 to 9:
>>>for i in range(10): print(i, end=' ')0 1 2 3 4 5 6 7 8 9
Notice that when you’re within IDLE, thisforloop is like any other: You need to type an extra blank line in order to terminate it.
4.2.18 Squeeze Multiple Statements onto a Line
If you have a lot of statements you want to squeeze onto the same line, you can do it—if you’re determined and the statements are short enough.
The technique is to use a semicolon (;) to separate one statement on a physical line from another. Here’s an example:
>>>for i in range(5): n=i*2; m = 5; print(n+m, end=' ')5 7 9 11 13
You can squeeze other kinds of loops onto a line in this way. Also, you don’t have to use loops but can place any statements on a line that you can manage to fit there.
>>>a = 1; b = 2; c = a + b; print(c)3
At this point, some people may object, “But with those semicolons, this looks like C code!” (Oh, no—anything but that!)
Maybe it does, but it saves space. Keep in mind that the semicolons are statement separators and not terminators, as in the old Pascal language.
4.2.19 Write One-Line if/then/else Statements
This feature is also called anin lineifconditional. Consider the following if/else statement, which is not uncommon:
turn = 0 ... if turn % 2: cell = 'X' else: cell = 'O'
The bookPython Without Fearuses this program logic to help operate a tic-tac-toe game. On alternate turns, the cell to be added was either an “X” or an “O”. The turn counter, advanced by 1 each time, caused a switch back and forth (atoggle) between the two players, “X” and “O.”
That book replaced the if/else block just shown with the more compact version:
cell = 'X' if turn % 2 else 'O'true_exprifconditionalelsefalse_expr
If theconditionalis true, then thetrue_expris evaluated and returned; otherwise thefalse_expris evaluated and returned.
4.2.20 Create Enum Values with “range”
Many programmers like to use enumerated (or “enum”) types in place of so-called magic numbers. For example, if you have acolor_indicatorvariable, in which the values 1 through 5 represent the values red, green, blue, back, and white, the code becomes more readable if you can use the color names instead of using the literal numbers 1 through 5.
You could make this possible by assigning a number to each variable name.
red = 0 blue = 1 green = 2 black = 3 white = 4
This works fine, but it would be nice to find a way to automate this code. There is a simple trick in Python that allows you to do that, creating an enumeration. You can take advantage of multiple assignment along with use of therangefunction:
red, blue, green, black, white = range(5)
The number passed torangein this case is the number of settings. Or, if you want to start the numbering at 1 instead of 0, you can use the following:
red, blue, green, black, white = range(1, 6)
4.2.21 Reduce the Inefficiency of the “print” Function Within IDLE
Within IDLE, calls to theprintstatement are incredibly slow. If you run programs from within the environment, you can speed up performance dramatically by reducing the number of separate calls toprint.
For example, suppose you want to print a 40 × 20 block of asterisks (*). The slowest way to do this, by far, is to print each character individually. Within IDLE, this code is painfully slowly.
for i in range(20): for j in range(40): print('*', end='') print()
You can get much better performance by printing a full row of asterisks at a time.
row_of_asterisks = '*' * 40 for i in range(20): print(row_of_asterisks)
But the best performance is achieved by revising the code so that it calls theprintfunction only once, after having assembled a large, multiline output string.
row_of_asterisks = '*' * 40 s = '' for i in range(20): s += row_of_asterisks + '\n' print(s)
This example can be improved even further by utilizing the string classjoinmethod. The reason this code is better is that it uses in-place appending of a list rather than appending to a string, which must create a new string each time.
row_of_asterisks = '*' * 40 list_of_str = [] for i in range(20): list_of_str.append(row_of_asterisks) print('\n'.join(list_of_str))
Better yet, here is a one-line version of the code!
print('\n'.join(['*' * 40] * 20))
4.2.22 Place Underscores Inside Large Numbers
In programming, you sometimes have to deal with large numeric literals. Here’s an example:
CEO_salary = 1500000
这些数字在编程难以阅读code. You might like to use commas as separators, but commas are reserved for other purposes, such as creating lists. Fortunately, Python provides another technique: You can use underscores (_) inside a numeric literal.
CEO_salary = 1_500_000
Subject to the following rules, the underscores can be placed anywhere inside the number. The effect is for Python to read the number as if no underscores were present. This technique involves several rules.
You can’t use two underscores in a row.
You can’t use a leading or trailing underscore. If you use a leading underscore (as in_1), the figure is treated as a variable name.
Youcanuse underscores on either side of a decimal point.
This technique affects only how numbers appear in the code itself and not how anything is printed. To print a number with thousands-place separators, use theformatfunction or method as described in Chapter 5, “Formatting Text Precisely.”