Strings
0. Learning objectives
- Define a string (sequence of characters)
- "Math" operations with and between strings?
- Introduce the idea of index and indexing
- I just want a piece, thanks! slicing strings
1. Strings
|
How would you define a string like If your quotes are not matching, you get a
As long as your quotes at the beginning and the end of the string match (two single or two
double), you can include the other quote inside your string. For example
|
![]() Just in case you want to play with strings at lunch! |
But what if you want to have both types of quotes within a string? You can do that by using what is
called an escape sequence. An escape sequence uses a special character to let Python know that
the following character should not be interpreted using the usual syntax rules. In other words,
we are escaping for a moment the interpretation rules, but just for the following character. In
Python all the escape sequences start with the backslash character (\). Using escape
sequences, we can create strings like "I'd love to hear you say \"hello\" in Arabic".
Because we escaped the double quotes inside the string, Python treats them as regular characters instead
of special one indicating the beginning or end of a string. (Try to write the string above without the
backslashes in Brython and see what happens!) You might notice that, when you enter that string in
Python, the interpreter might switch the quotes used to define the string. That's fine since it it not
really changing your original string, just the way it is represented.
What if you want to include an actual \ in your string? Well.. you can escape the backslash
that using a backslash as well: "The backslash character looks like this: \\.". Remember,
the escaping only applies to the character following the \.
There are several escape sequences that Python recognizes:
| Escape sequence | Description |
\' |
Single quote |
\" |
Double quote |
\\ |
Backslash |
\t |
Tab |
\n |
New line |
\r |
Carriage return |
The new line (\n) is very commonly used since it can be used to send a piece of your string
to the next line when it is displayed (e.g. "Hello\nWorld!").
These escape characters are rendered (generated) when the string is displayed on the screen using the
print() function. Try to use all the example we have seen so far as arguments for the
print() function in Brython! (e.g. print("Hello\nWorld!")).
2. Operations with strings
Great now that we can define strings, what can we do with them? (You should try all the following examples in Brython... it's not hard, it is at the bottom of your screen!) .
One thing that we can do, since a string is a sequence of characters, is to use the function
len() (remember that you can get more information about a function using the
help() function - help(len)) to tell us how long the string is (e.g.,
len("Welcome to CSCI0145!")). What is the length of the empty string ""?
We can also concatenate strings using the + operator. Try
"How do you " + "concatenate strings?" in Brython and see what the result of this
expression is. One thing you have to be careful when using the + operator is that it will
only work if its behavior is define based on the operands. For example, try to add a string to a number
("I like the number " + 3). Python is going to complain because it first saw a string so it
is expecting the second operand to be a string as well and, when it finds a number, it doesn't know how
to handle it. What does the error say? The same is true if you try to add a string to a number
(3 + " is a cool number!"). Once again, Python doesn't know how to handle it, although it
notify us using a different error. Which one?
To solve this problem, you can convert a number to a string using the str() function:
str(3) + " is a cool number", as we saw when we were discussing types and expressions. To
add a couple of useful functions to the conversion-between-types family, you can use int()
and float() to convert strings into numbers (e.g. int("32"), and
float("37.2") will both convert the strings into an integer and a floating point number
respectively). Try the following conversion in Brython to get a feeling about how these function work
and where they don't.
float("42")int("42")float("13.7")int("13.7")int("a")float("ciao!")
As an alternative to converting between types, if you are only interested in displaying the result for
humans and not in creating and actual string that you will need later for further computation, you can
use the print() function to combine multiple objects you want to display. If you pass more
than one argument to the print() function, it will display them one after the other
separated by a space and terminated by the new line character.
The arguments don't even have to be of the same type. Try out the following:
print(3, "is my favorite number!")print("Today is quite warm.", "It must be at least", 70)
Take a look at help(print) to see how you can modify the default behavior: you can, for
example, change the character used to separate the arguments when they are displayed
(sep=' '), or change the termination character (end='\n').
>>> help(print)
Help on built-in function print in module builtins:
print(...)
print(value, ..., sep=' ', end='\n', file=sys.stdout, flush=False)
Prints the values to a stream, or to sys.stdout by default.
Optional keyword arguments:
file: a file-like object (stream); defaults to the current sys.stdout.
sep: string inserted between values, default a space.
end: string appended after the last value, default a newline.
flush: whether to forcibly flush the stream.
The arguments sep and end highlighted above have assignment statement in the
function header! These types of arguments, known as keyword arguments allow you to define default
values for some of the arguments in your functions. If you want to overwrite those default values, you
can call the function and specify the argument using its name. For example, try
print(3, "is my favorite number!", sep="---", end=" not!")
We will not mess around with file and flush since they determine where and how
things are display and, right now, we are happy with seeing printed values show up where they do, but
feel free to play around with sep and end.
Back to operations with strings, another thing that you can do is multiply a string by an integer. This
results in the string being repeated that many times. Try, for example
"echo... " * 3 or 5 * "long echo... ". Here is a cool one. What do you think
will happen if you multiply a string by 0? (Think before trying it out in Brython).
Since strings are values, you can assign them to variables: hello = "Hello World!" and all
the operation that we have seen can be applied to the variables containing strings.
3. Indexing
So far, we've been doing some simple operations with strings, but there is more! What if we want to extract a portion of a string? Or, what if we want to reverse a string? This brings up the idea of "iterating" through the characters in a string, which will build up to a more general approach when we discuss about iteration and lists.
Let's start off by answering the question: how do we retrieve a character at a particular index (location) in the string?
This index is like the "address" of the character in the string, starting from the left. We can retrieve a character at a particular index using square brackets, typically after the variable name containing the string.
Consider the string "Do you speak whale?", stored in a variable called
message. If you think about every character being stored in its own little box within the
larger box for the variable message (I know... it sounds like Python is all about boxes),
and each little box getting a number starting from 0 for the box to the very left, then
each character can be accessed with the appropriate index - the box number. In general, we can retrieve
a character at a particular index using message[index] where
index is an integer.
Try typing in message = 'Do you speak whale?' in Brython. As we have seen, if you type
len(message), you will get the length of the string (19). Notice that the
index only goes up to 18. This is because Python (like many other languages
such as C and Java) starts indexing at 0. If we start counting at
0, the last index in a string s is len(s) - 1. If you try
to access message[19] (or any number greater than len(s) - 1),
Python will give you an IndexError since you are out of the bounds of your
string.
What happens if we pass a negative index into the string? It turns out that this allows you to
index the string in reverse order. In other words, a negative index will start the indexing at
the end of the string (starting at -1 instead of 0 (which is the
beginning of the string). For example, message[-1] will retrieve the question mark
? and message[-6] will retrieve the w.
So, if you are given a (negative) backward index
j (starting from the right), what is the
equivalent forward index (starting from the left)?
j is a negative integer and i is a positive integer. If they both
refer to the same location in the string, from the figure above, you can see that the
relationship between i and j satisfies
i - j = len(message), therefore i = len(message) + j:
message[i] = message[len(message)+j] (remember that j is
negative).
4. Slicing
So we can extract a particular character from a string. That's cool! But what about extracting a
portion of a string? For example, what if we just want to extract the word whale
from our previous message? We can do this by slicing the string. Instead of using a single index,
we can use the following syntax to extract aa substring from some original string stored in our
variable message:
message[start:end:step]
where start is the index we want to start the extraction at, end is the index
in which we will terminate the extraction (not including the character at this index) and
step is the number of steps we take before we grab the next character (a step of
2, for example, will grab every other character between start and
end - not included).
You don't always have to use start, end, and step. If you omit
them, Python will use the defaults of start = 0,
end = len(message) - 1 and step = 1 if you are going forward. If
Python detects you are slicing in reverse order (step = -1), the defaults will
be start = len(message) - 1 and end = 0. In other words, it will go
backward.
You can also omit the step, and only using a single colon to slice. In this case,
step will be assumed to be 1. For example, message[13:] will give
you whale?. What happens if end < start? You should see an empty string
''. (This will also happen if the end > start and the step is
negative).
One way to think about it is:
Python will try to go from start to end using the
step. If it can do it, it will give you a string made of the characters it collects, if it
cannot, it will give you an empty string.
Also, when you are slicing, Python will not complain if end is passed the end of the string.
For example message[:40] will simply return you the whole string "Do you speak whale?".
Think about these examples and then try them out in Brython!
message[13:18]message[11:6]message[11:6:-1]message[::-1]message[:5] + message[5:]message[1::2]
'whale'''(an empty string)'kaeps''?elahw kaeps uoy oD''Do yo''oyusekwae?'
Here are some more examples that you can play with. Try to guess the outcome before you run the code.
