15-112 Lecture 6 (Thursday, July 11, 2013)

Lists

Lists are ordered, indexable collections. We've seen lists before in the sense that strings are essentially lists of characters. With lists, we can select items by their index number, or range of indexes. We can splice lists together, append items, remove items, and get the length of the list, etc

Let's see some examples:


#!/usr/bin/python

names = [] # Creates an empty list of names
names = ["Greg", "Dave", "Tom", "Klaus"] # Creates a list of 4 strings

print names    # Prints the whole list
print names[0] # Prints "Greg"
print names[3] # Prints "Klaus"

names[1] = "David"  # Changes names[1] from "Dave" to "David"
print names         # Prints the whole list, as modified

names.insert(2, "Santa Claus") # Inserts a name using insert()
print names                    # Prints the whole list, as modified

names = names[0:2] + ["Easter Bunny"] + names[2:] # Inserts a name by splicing
print names

del names[2]     # Remove an item by the del operator
print names      # print the modified list

names = names[0:2] + names[3:]   # remove and item by splicing
print names                      # print a modified list


names.remove ("Greg")   # Remove an item by seaching for the value
print names             # print a modified list

names.append ("Gregory")   # Add an item via the append method
print names             # print a modified list

names = names[0:] + ["Superman"]
print names             # print a modified list

print len(names)        # Prints the number of items within the list
  

What are the take-aways?

Lists and the "for loop"

As you might imagine, it is realtively easy to walk through, or traverse, a List with a for loop. But, Python provides an easier way, too. The "for loop" automatically traverses a List, taking one step per iteration, as shown below:


#!/usr/bin/python

names = ["Greg", "Dave", "Tom"]

# Traversal of a list via a while loop and index variable
index = 0
while (index < len(names)):
  name = names[index]
  print name
  index = index + 1

print ""


# Traversal of a list via a for loop
for name in names:
  print name

  

What are the take-aways?

For loops, Lists and "range()"

The range() function creates a list of ints within the specified range. The most common use of this, however, is probably not to create a list of numbers for some arbitrary reason -- but instead to provide a pretty way of controlling a loop's iteration.

It is important to note that the range() function is inclusive of the starting index, but exclusive of the ending index. This is to make a programmer's life easier when creating a range of indexes for lists and strings, for which the last index is one less than the len().

Consider, for example, the examples below:


#!/usr/bin/python

oneTo10 = range(1,11) # 1,2,3,4,5,6,7,8,9,10
print oneTo10

negTwoToTen = range(-2,11) # -2,-1,0,1,2,3,4,5,6,7,8,9,10
print negTwoToTen

evens = range (0,11,2) # 0,2,4,6,8,10 NOTICE WE'RE STEPPING BY TWO (2)
print evens

odds = range(1,11,2) # 1,3,5,7,9
print odds

# Print squars of 1 - 10
for number in oneTo10:
  print number*number

  

What are the take-aways?

sort() and sorted()

The sorted() function and the .sort() method sort lists. They are somewhat powerful and agile, but in their simplest form they sort lists in a natural way. The key difference between the two is that .sort() sorts the list in place, whereas sorted() returns a new sorted list, leaving the original unchanged. Please enjoy the example below:


  #!/usr/bin/python
  
  names = ["Greg", "Tom", "Dave", "Guna"]
  numbers = [1, 3, 5, 7, 2, 4, 6, 8 ]

  sortedNames = names.sort()
  print sortedNames   # sorted
  print names         # sorted

  sortedNumbers = sorted(numbers)
  print sortedNumbers  # sorted
  print numbers        # unsorted
  

Negative List Indexes

List indexes -- negative indexes index backward from the end, with -1 (negative one) representing the last element of the array, -2 the second to last, etc. Please note that, the beginning of a list is at index 0, but the end of a list is at index -1. This is because there is no such thing as -0, so they had to start at -1.

The ability to use negative numbers to walk backwards through a list is very convenient when this is what we want to do -- but also dangerous if we good up an index variable and "Negative on accident".

Please consider the example below:


#!/usr/bin/python

numbers = [1, 2, 3, 4, 5]

print numbers
try:
  for index in range(0, 10):
    print numbers[index]
except IndexError:
  print "We counted forward up to index " + str(index) + ", at which time " \
        + "we got  an IndexError."


print ""
print ""


print numbers
try:
  for index in range(-1, -10, -1):
    print numbers[index]
except IndexError:
  print "We counted backward up to index " + str(index) + ", at which time " \
        + "we got  an IndexError."

           

List Comprehensions

Python has a feature called List Comprehensions designed to make it easier to initialize lists. Comprehensions enable lists to be initialized using loops to generate lists, and then using if statements to filter them. Check out the examples below which show the initialization of a list with one loop, the filting of a similar comprehension using an if, the initialization of a list using multiple loops, and the filtering of the same. together they illustrate the basic idea of specifying the result, specifying the loop(s) that generate it, and then specifying an if to filter it.


numbers = [ number for number in range(10) ]
print numbers

evens = [ number for number in range(10) if ((number%2) == 0)]
print evens

adjectives = ["Fast", "Slow", "Big", "Small" ]
nouns = [ "Car", "Boat", "Truck", "Plane" ]
combinations = [ (adjective, noun) for adjective in adjectives \
                                   for noun in nouns ]
print combinations

boatCombinations = [ (adjective, noun) for adjective in adjectives \
                                        for noun in nouns  \
                                        if (noun == "Boat") ]
print boatCombinations