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.