2023-01-23
We have already seen simple examples using strings as labels and titles in plots. Python provides many powerful features for text processing, but we will focus just on the simplest ones that are commonly needed in mathematical and scientific computing.
The aim of this lesson is to understand how to create and manipulate strings in Python, and how to produce formatted output.
By the end of the lesson, you should know how to
A Python string consists of a sequence of characters, and we can define a string by delimiting the characters with two single quotes or two double quotes. The strings s1 and s2 produced by the following commands are treated by Python as the same string: it does not matter that one uses single quotes and other uses double quotes.
s1 = 'A simple string'
s2 = "A simple string"
One reason for allowing single or double quotes is that sometimes you want to include quotes as part of the string.
s3 = '"I like history," Netherton said.'
s4 = "He usually wasn't there in the daytime."
You can also use the backslash ‘\’ as an escape character in the tricky case when your string contains both kinds of quote marks.
s5 = '"Stealing Mr. Zubov\'s oldest whiskey," said Ossian'
The print function will print a string to the console, stripping away the delimiting quotes (and any escape characters). Thus, print(s5) will display
"Stealing Mr. Zubov's oldest whiskey," said Ossian
If you actually want to print a backslash, you have to escape it; for example,
print('Here is a backslash \\.')
will display
Here is a backslash \.
The newline character ‘\n’ causes the text to jump to the next line. For example,
print('This text appears\non two lines.')
produces
This text appears
on two lines.
You can prevent jumping to a new line by finishing a line with the backslash character ‘\’ as in the following example.
print('This text appears \
on one line.')
produces
This text appears on one line.
There is a third type of string that uses triple quotes for text that spans more than one line. For example,
s6 = '''Examples of container classes include
* Lists
* Tuples
* Arrays
* Strings
* Dictionaries'''
print(s6)
produces
Examples of container classes include
* Lists
* Tuples
* Arrays
* Strings
* Dictionaries
We can refer to the kth character in a string s as s[k]. As with lists and arrays, the characters are indexed from 0 and we can take slices of a string. For example, if
s = 'The Website of Dreadful Night'
then s[4] equals ‘W’, s[4:11] equals ‘Website’ and s[-5:] equals ‘Night’.
However, unlike a list or an array, a string is not mutable. Doing
s[-5] = 'L'
raises TypeError: 'str' object does not support item assignment. Although a string cannot be modified, there are ways to create new string based on an existing one. For example,
new_s = s.replace('N', 'L')
print(new_s)
produces
The Website of Dreadful Light
The len function works for strings just as for lists, so len(new_s) = 29.
Python uses + as a concatentation operator for strings. Thus,
word1 = 'Flynne '
word2 = 'Fisher'
print(word1+word2)
produces
Flynne Fisher
Repetition is achieved when you multiply by a positive integer:
print(3 * 'Cayce')
produces
CayceCayceCayce
The upper and lower methods return a string with all characters changed to upper and lower case, respectively. Thus,
s = 'Virtual Light'.upper()
print(s)
produces
VIRTUAL LIGHT
whereas
s = 'Mona Lisa Overdrive'.lower()
print(s)
produces
mona lisa overdrive
The comparison operator == is used to test if two strings s1 and s2 are equal: s1 == s2 returns True if the strings match exactly, and False otherwise.
Often we want to create a string that incorporates the values of some variables. Recall in Lesson 4 we used the command
sol = root_scalar(f, method='brentq', bracket=(0.5,1.0))
to find a solution of the equation \(\sin(4x)=\log(x)\). The solution is stored as sol.root. A formatted string literal is a special kind of string that prepends an f before its opening quote. Inside the string, the text between any pair of braces { and } takes on a special interpretation. For example,
s = f'Solution {sol.root} found after {sol.iterations} iterations.'
print(s)
will insert human-readable values of the variables sol.root and sol.iterations in the string and so produce
Solution 0.8317259339759461 found after 7 iterations.
We can use a format specifier to gain precise control over how the value of a variable is represented in a string. The simplest format specifier is a positive integer, which is interpreted as a minimum field width. In the examples that follow, we will use the ‘|’ character as a visible delimiter around each {...} so that you can see where the output begins and ends.
name = 'Wilf'
age = 32
print(f'|{name:10}| -> |{age:5}|')
produces
|Wilf | -> | 32|
Notice that, within their fields, strings are left-justified whereas integers are right-justified. The field width will be ignored if it is smaller than the minimum necessary field width:
factorial_10 = arange(1, 10).prod()
print(f'|{factorial_10:3}|')
produces
|362880|
For a floating-point value, a format specifier of the form m.nf will print n digits after the decimal point in a field of width m. For example,
print(f'|{pi:8.4f}|')
produces
| 3.1416|
Notice that floats are right-justified, the same as ints. For scientific notation, replace the f with e.
print(f'|{exp(10):10.5e}|')
produces
|2.20265e+04|
If you are not sure how wide the field needs to be, setting m to 0 will give result in the minimum necessary field width. For example,
print(f'|{exp(-10):0.7e}|')
produces
|4.5399930e-05|
The print function has two optional arguments sep and end that have the default values ' ' and \n, respectively. If you provide more than one string argument, then print will print them separated by sep and add end at the end of the line. Thus,
print('Collage', 'Minus', 'Glue')
gives
Collage Minus Glue
whereas
print('Collage', 'Minus', 'Glue', sep=' * ')
gives
Collage * Minus * Glue
Probably the most common use of end is simply to inhibit jumping to a new line, so that a single line can be built up in stages using multiple print statements.
print('This sentence', end=' ')
print('continues on the same line.')
This might not work in an interactive shell, but it will if you run the commands from a file.
When defining a function, you can provide a docstring by inserting a triple quoted string immediately following the def line. For example, in the case of our solve_quadratic function from Lesson 4, we could do the following
def solve_quadratic(a, b, c):
"""Solve the quadratic equation ax^2 + bx + c = 0.
Warning: the coefficients a, b, c must be real, and the
discriminant must be positive, so that two real roots are
returned.
"""
sqrt_dscr = sqrt(b**2 - 4*a*c)
x_plus = (-b + sqrt_dscr ) / ( 2 * a )
x_minus = (-b - sqrt_dscr ) / ( 2 * a )
return x_plus, x_minus
In IPython, if we import solve_quadratic then the command ?solve_quadratic will print the message
Signature: solve_quadratic(a, b, c)
Docstring:
Solve the quadratic equation ax^2 + bx + c = 0.
Warning: the coefficients a, b, c must be real, and the discriminant
must be positive, so that two real roots are returned.
File: /tmp/ipykernel_6336/2636809440.py
Type: function
The docstring should begin with a one-line description of the function, followed if necessary by a blank line and then any further details.
This lesson described how
In the Tutorial from the official Python documentation, the basic properties of strings are covered in the section 3.1.2 Strings, and you can find more details about formatted printing in the section 7.1 Fancier Output Formatting.