Lesson 3: Fun with Strings and Lists
Today's lesson covers two important types of Python variables:
strings and lists.
============== Strings ================
You've already used simple strings like "Hello, world".
But Python can do all sorts of useful things with strings. It's a
great language for handling text (this lesson will only scratch the surface).
You may remember from the discussion on earlier lessons that you can
use + to "concatenate" (stick together) two strings. Like this:
firstname = "Monty"
lastname = "Python"
fullname = firstname + " " + lastname
You can also use += to build up a string by adding stuff on the end of it.
fullname += lastname
is just a shorthand way of saying
fullname = fullname + lastname
So you could build up that name like this:
fullname = "Monty"
fullname += " "
fullname += "Python"
You can get the length of that string (how many letters) with len(fullname)
You'll see len again for other Python data types, so it's worth
remembering it.
============== Splitting strings ===================
What if you want to go the other way? What if you have a full name,
like "Linus Torvalds", and you want to split it into firstname and lastname?
Python strings have a handy way of splitting strings. It works like this:
>>> fullname = "Linus Torvalds"
>>> fullname.split(" ")
['Linus', 'Torvalds']
As you see, the full name has been split at the space into two
separate strings.
The syntax, fullname.split(" "), might look a little odd. This is the
first time in this course that we've encountered object-oriented code.
"Object oriented" just means that Python objects, like strings, can
have their own set of functions, like split(). If fullname is a string
and you say fullname.split(" "), Python knows to call the function that
splits strings. If fullname was some other type of object, like an
integer number or a dictionary or a type you'd defined yourself, split()
might mean something totally different, or might not exist at all.
If that paragraph made no sense to you, don't worry about it. Just
remember that if you have a string named s, you can call s.split().
You can split on any set of characters, not just spaces. So if someone
gave you a comma-separated list, maybe something that came out of a
spreadsheet, like
>>> veggies = "peas,green beans,spinach,corn,squash"
you could say
>>> veggies.split(',')
['peas', 'green beans', 'spinach', 'corn', 'squash']
But about that ['Linus', 'Torvalds'] thing -- what is it really?
==================== Lists ========================
['Linus', 'Torvalds'] is what's called a list. You can have any number
of items in a list, and you can reference them by number using square
brackets, with 0 denoting the first item:
>>> fullname = "Linus Torvalds"
>>> names = fullname.split()
>>> print "Hello,", names[0]
Hello, Linus
Lists can contain any type, and the items don't all have to be the
same type. A list like this:
mylist = [1, "eeny meeny miny moe", 3.14159]
is perfectly valid. Lists can even contain other lists, but let's not
worry about that just now.
You can loop over the items in a list:
for n in names :
print n
================ Slices =====================
Okay, firstname and lastname are easy if there are only two names.
What about people with multi-part names?
>>> fullname = "Guido van Rossum"
>>> names = fullname.split()
>>> names
['Guido', 'van', 'Rossum']
You can still use names[0] to get the first name. But the last name is
no longer names[1] -- that would be "van". Python gives you a neat way
of referring to several list items at once, called slices, where you
can specify a start and end position with a colon in between. So if
you knew Guido had a 2-part last name, you could say
>>> names[1:3]
['van', 'Rossum']
Or you might want to say "Give me everything except the first name".
How would you do that? You can get the number of items in the list
with len, the same way you get the length of a string. Then use it
to take a slice (I'll space things out to make it more readable):
>>> names[ 1 : len(names) ]
['van', 'Rossum']
Getting everything to the end of the list, though, is such a common case
that if you include a colon with nothing after it, Python assumes you
want everything to the end of the list:
>>> names[1:]
['van', 'Rossum']
============ Similaries between lists and strings ===========
Many of the things you can do with lists, you can do with strings,
and vice versa. You can take slices of a string:
>>> fullname[0:5]
'Guido'
>>> fullname[6:]
'van Rossum'
and you can loop over a string's individual characters:
for c in fullname :
if c == " " :
print "It's a space!"
You can add to the end of a list; but instead of using += like you
would for strings, use append: names.append("Jr.")
================== Homework ======================
1. How would you count the number of words in a single string?
Assume words are separated by spaces ... don't worry about
things like newlines, commas or hyphens.
2. What does an index of [-1], or another negative number mean in a
list or string? Take a guess, then try it and see if you were right.
3. Who is Guido van Rossum and why am I using him as an example?
4. Rewrite the exercise from lesson 2, the one where
you printed "one", "two", "three", "four", "five",
using a list instead of a series of if-elif.
(A few people already posted solutions that worked that way
in their lesson 2 answers. If you already did this for lesson 2, no
need to do it again. If you read other people's, it's still worth
writing it yourself now without going back and looking.)
5. This one's a little harder, but give it a try if you have time.
Plot a histogram graph from a list of numbers, with each number in
the list on its own line.
For instance, if you start with numbers like this:
vals = [ 0, 2, 4, 8, 16, 18, 17, 14, 9, 7, 4, 2, 1 ]
you might plot something like this:
**
****
********
****************
******************
*****************
**************
*********
*******
****
**
*
where the first line has no stars, the second has two, then 4, etc.
Hint: you'll need two loops, one inside the other.