Part 5: Lists and for loops — Python Värmland

Python Värmland

Part 5: Lists and for loops

The short version - for experienced programmers

# LISTS

rooms = ["kitchen", "living room", "bathroom", "bedroom"]

# Print all rooms
print(rooms)

# How many rooms are there?
print(f"There are {len(rooms)} rooms")

# Which is the first room in the list?
print(f"First room: {rooms[0]}")
# rooms[0] == first in the list

# Which is the second room in the list?
print(f"Second room: {rooms[1]}")
# rooms[1] == second in the list

# How about the LAST room?
print(f"Last room: {rooms[-1]}")
# rooms[-1] == the last

# And the second to last room?
print(f"Second to last: {rooms[-2]}")
# rooms[-2] == second to last

# What if I want several entries?
print(f"First two entries: {rooms[0:2]}")
# rooms[0:2] or rooms[:2] == first two

# Delete entry by index
del rooms[0]

# Delete by value
rooms.remove("bathroom")

# FOR LOOPS

for room in rooms:
    print(room)

The full version - for beginner programmers

Answer to the exercise in Part 4

Here's one possible answer to the exercise from Part 4.

# Make Python's "random" module available to us
import random

# keep_playing will tell us if the player wants to
# continue or not. For now, let's assume "yes".
keep_playing = "y"

# To allow the player to play many times, we add a
# while loop around the game code itself. Please
# note that this means that all our previous code
# has to be indented another four spaces, to tell
# the computer that it's part of the new while
# loop
while keep_playing == "y":

    max_number = input("Highest number for guess? ")
    max_number = int(max_number)

    # In the random module, there's a function called
    # randint. We can use it to give us any integer
    # from 1 to max_number.
    number = random.randint(1, max_number)

    print(f"I'm thinking of a number between 1 and {max_number}.")
    print("Try to guess which one it is.")

    # Let's give the guess variable a starting number
    # that we know will never be correct.
    guess = 0

    # Keep track of how many guesses the player has used.
    num_guesses = 0

    # Until guess is equal to the number, repeat this
    # loop:
    while guess != number:
        guess = input("What's your guess? ")
        guess = int(guess)  # Convert guess to integer

        # num_guesses += 1 is a shorthand for:
        # num_guesses = num_guesses + 1
        num_guesses += 1

        # Check if it is too low or too high
        if guess < number:
            print("Your guess is too low.")
        elif guess > number:
            print("Your guess is too high.")

    # We have now exited the loop, which means that
    # guess must be equal to number, IE, correct.
    print(f"Correct! Well done! It took {num_guesses} guesses.")

    keep_playing = input("Play another (y/n)? ")

Lists

All the variables we've talked about so far have been a single point of data. But what if we want to keep track of, say, 10,000 people? Having that many ordinary variables would be very impractical. Therefore, there are other types of variables that we can use, and now we're going to be talking about one of them: lists.

Making lists in Python is very simple:

names = ["Anna", "Betty", "Christine"]
print(names)

If we run that, we get the following output:

['Anna', 'Betty', 'Christine']

So, using a single variable - a list - called names, we could store three names. We could store more names of course, thousands or more if we wanted to.

Before we continue - just a word of warning. Do not make a list called list. It will cause problems, because there is already a function in Python called list.

As you may have noticed, all the entries in our list are string variables (you can tell, because of the quotation marks). But we can have other types of variables too:

random_things = ["Hello", 4, "Saxophone", "Blue"]
print(random_things)

and that gets us:

['Hello', 4, 'Saxophone', 'Blue']

You can also make empty lists, by not putting anything inside [ and ]:

people_who_like_nickleback = []

How to check how long a list is

With the len function (short for "length"), we can see how many entries there are in a list - that is, how long the list is.

people_who_like_nickleback = []
print(len(people_who_like_nickleback))

And that, of course, get us:

0

If you're confused by having the len function "inside" the parentheses of len, there is no need to be. What this does is it first calls the len(people_who_like_nickleback) function. It then takes that function's return value (which is zero, since that's the length of the list), and hands it off to the print function. So:

# This:
print(len(people_who_like_nickleback))

# Becomes this:
print(0)
# since 0 is the return value of the len function
# in this case, since the list is empty.

How to access specific data in a list

Let's say you have a list of rooms in a house - here are some very useful ways of using that list:

rooms = ["kitchen", "living room", "bathroom", "bedroom"]

# Print all rooms
print(rooms)

# How many rooms are there?
print(f"There are {len(rooms)} rooms")

# Which is the first room in the list?
print(f"First room: {rooms[0]}")
# rooms[0] == first in the list

# Which is the second room in the list?
print(f"Second room: {rooms[1]}")
# rooms[1] == second in the list

# How about the LAST room?
print(f"Last room: {rooms[-1]}")
# rooms[-1] == the last

# And the second to last room?
print(f"Second to last: {rooms[-2]}")
# rooms[-2] == second to last

When we run that, we get:

There are 4 rooms
First room: kitchen
Second room: living room
Last room: bedroom
Second to last: bathroom

By using rooms[0] you get the first and rooms[1] gives you the second, and so on. It might seem strange that it starts with 0 for the first, rather than having 1 for the first. It's like that for historic reasons, and most programming languages work that way so we just have to get used to it.

Also, we see that rooms[-1] refers to the last entry in the list. So, why not rooms[-0] to make it consistent with rooms[0] being the first? Well, that's because -0 doesn't make much sense - it's technically the same as 0.

If you try to access a list entry that doesn't exist, you will get an error similar to this:

print(rooms[42])

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: list index out of range

The important part to look at here is the last line: IndexError: list index out of range. The "index" is the number you put between [ and ], or 42 in this case. And that is "out of range", where the "range" is 0, 1, 2, and 3 (since we have four rooms in our list).

This is getting tedious

I know. Hang in there - there are just a few more things we need to cover about how to manipulate lists before we can move on to the slightly more interesting for loops.

How to add items to lists

To add something to the end of a list, you do this:

rooms.append("man cave")

We have now added a fifth room - "man cave" - to the end of the list. If we instead want to insert a room at a specific point in a list, we use the insert function which takes two arguments (remember, the "arguments" are the things inside the parentheses): where to insert it, and what to insert.

# 0 refers to where to insert it, so 0
# means first in the list. 1 would be
# in the second slot, etc. This does not
# overwrite what is already there.
# "laundry room" is what to insert.
rooms.insert(0, "laundry room")

What about removing things then?

There are two primary ways of doing that.

  1. If you know the index of the item you want to remove - in other words, if you know what number it has in the list - then you use del.
  2. If instead you know the value - the name of the room in our case - then you use the remove function.
# How to remove by index:
# 2 == the third room (since 0 == the first)
del rooms[2]

# How to remove a room by name:
rooms.remove("man cave")
# Typical that the man cave is the room
# that has to go, right?

But wait a minute - why is it del rooms[2] and not rooms.del(2)? That's a good question. The reason for this is because rooms.remove() is a function that "belongs" to the list. That function can only be used to remove things from lists. del, on the other hand, can be used to remove things both from lists and from other things - therefore, it doesn't "belong" to lists. This might sound a bit confusing, but don't worry about it. You don't even have to worry about remembering which one is which. Here's a little programmer secret for you: despite my 30+ years of programming experience, I google stuff left and right all the time. Even simple things like this. I had to google this while writing it. Don't feel like a failure if you google all the time too. We all do it.

Enough already - what about for loops?

Okay. We've now had a fairly extensive look at lists themselves. Now let's look at how we can use them in a more practical way. Take a look at this example:

movies = ["Quest for the Holy Grail",
          "Life of Brian",
          "Kung Fury",
          "Wonder Woman"]

# for loops lets us go through lists.
# We will go through this loop four times,
# because there are four entries in the list.
for movie in movies:
    # The variable "movie" is now an entry
    # from the list movies
    print(movie)

This will get us:

Quest for the Holy Grail
Life of Brian
Kung Fury
Wonder Woman

Neat, isn't it? for loops allow us to go through lists, setting a variable to each entry in the list in turn. On the other hand, while loops allow us to keep looping until a specific condition is no longer met, like we talked about in the previous part. So:

  1. Use for loops to go through lists, one item at a time.
  2. Use while loops to keep doing something until answer == correct_answer or something similar.

Let's make a proper program - list_maker.py

Time to do something useful. Well, sort of useful, we're not exactly expert programmers yet, but let's do our best. We are going to be making a very simple list-making program which we can then use to make grocery lists, todo lists, packing lists, or any other kind of simple list.

So let's get to it! Open IDLE, go to File and New file. Type in the following:

# Let's call our list 'items', since calling it
# 'list' is a bad idea.

items = []

user_input = ""

while user_input != "q":

    if len(items) == 0:
        print("The list is empty.")
    else:
        item_num = 0

        for item in items:
            print(f"{item_num}: {item}")
            item_num += 1

    # Just print an empty line
    print()
    user_input = input("Add item or quit (a/q)? ")

    if user_input == "a":
        new_item = input("What should I add? ")
        items.append(new_item)

print("Goodbye!")

There. Now save it (Ctrl-s), giving it the name list_maker.py, and then run it with F5. Here's what it looked like when I ran it:

The list is empty.

Add item or quit (a/q)? a
What should I add? Eggs
0: Eggs

Add item or quit (a/q)? a
What should I add? Bacon
0: Eggs
1: Bacon

Add item or quit (a/q)? a
What should I add? Bread
0: Eggs
1: Bacon
2: Bread

Add item or quit (a/q)? a
What should I add? Thunderpants
0: Eggs
1: Bacon
2: Bread
3: Thunderpants

Add item or quit (a/q)? q
Goodbye!

Exercise

This little program above has some obvious missing features. One of these is that you can't delete items in the list. Therefore, your exercise is to add the following:

  1. It must be possible to delete items by pressing d.
  2. After the user has pressed d, but before you attempt to delete anything, check if there are any items in the list. If there are not, print a message saying so, and abort the deletion.
  3. If the list is not empty, ask the user for which item number to delete, and then delete it.

You do not have to worry about what happens if the user gives an invalid number to delete, such as -3 or 431. We will deal with that in later parts of this tutorial. Good luck! And remember: googling is okay!

Previous: Part 4: While loops | Next: Part 6: Creating functions | Index

Understood
This website is using cookies. More details