Computer Science 15-110, Spring 2011
Class Notes:  Two-Dimensional Lists


  1. Creating 2d Lists
  2. Getting 2d List Dimensions
  3. Nested Looping over 2d Lists
  4. Printing 2d Lists

Two-Dimensional Lists
  1. Creating 2d Lists

    1. Static Allocation

      # create a 2d list with fixed values (static allocation)
      a = [ [ 2, 3, 4 ] , [ 5, 6, 7 ] ]
      print a

    2. Dynamic (Variable-Length) Allocation

      1. Wrong:  Cannot use * (Shallow Copy)

        # Try, and FAIL, to create a variable-sized 2d list
        rows = 3
        cols = 2

        a = [ [0] * cols ] * rows  # Error:  creates shallow copy

        print "This SEEMS ok.  At first:"
        print "   a =", a

        a[0][0] = 42
        print "But see what happens after a[0]=42"
        print "   a =", a


      2. Right:  Append Each Row

        # Create a variable-sized 2d list
        rows = 3
        cols = 2

        a=[]
        for row in range(rows): a += [[0]*cols]

        print "This IS ok.  At first:"
        print "   a =", a

        a[0][0] = 42
        print "And now see what happens after a[0]=42"
        print "   a =", a


      3. Even Better:  make2dList() 

        def make2dList(rows, cols):
            a=[]
            for row in range(rows): a += [[0]*cols]
            return a

        rows = 3
        cols = 2
        a = make2dList(rows, cols)
        print "This IS ok.  At first:"
        print "   a =", a

        a[0][0] = 42
        print "And now see what happens after a[0][0]=42"
        print "   a =", a

  2. Getting 2d List Dimensions

    # Create an "arbitrary" 2d List
    a = [ [ 2, 3, 5] , [ 1, 4, 7 ] ]
    print "a = ", a

    # Now find its dimensions
    rows = len(a)
    cols = len(a[0])
    print "rows =", rows
    print "cols =", cols


  3. Nested Looping over 2d Lists

    # Create an "arbitrary" 2d List
    a = [ [ 2, 3, 5] , [ 1, 4, 7 ] ]
    print "Before: a =", a

    # Now find its dimensions
    rows = len(a)
    cols = len(a[0])

    # And now loop over every element
    # Here, we'll add one to each element,
    # just to make a change we can easily see
    for row in range(rows):
        for col in range(cols):
            # This code will be run rows*cols times, once for each
            # element in the 2d list
            a[row][col] += 1

    # Finally, print the results
    print "After:  a =", a


  4. Printing 2d Lists

    # Helper function for print2dList.
    # This finds the maximum length of the strings
    # in each column of a 2d list
    def getFieldWidths(a):
        rows = len(a)
        cols = len(a[0])
        fieldWidths = [0] * cols
        for row in range(rows):
            for col in range(cols):
                field = str(a[row][col])
                fieldWidths[col] = max(fieldWidths[col], len(field))
        return fieldWidths

    # Because Python prints 2d lists on one row,
    # we might want to write our own function
    # that prints 2d lists a bit nicer.
    def print2dList(a):
        if (a == []):
            # So we don't crash accessing a[0]
            print []
            return
        rows = len(a)
        cols = len(a[0])
        fieldWidths = getFieldWidths(a)
        for row in range(rows):
            if (row == 0):
                line = "[ ["
            else:
                line = "  ["
            for col in range(cols):
                if (col > 0): line += ", "
                field = str(a[row][col])
                for space in range(fieldWidths[col] - len(field)):
                    line += " "
                line += field
            line += "]"
            if (row == (rows-1)): line += " ]"
            print line

    # Let's give the new function a try!
    a = [ [ 1, 2, 3.4 ] , [ "wahoo", 55, 6 ] ]
    print2dList(a)

carpe diem   -   carpe diem   -   carpe diem   -   carpe diem   -   carpe diem   -   carpe diem   -   carpe diem   -   carpe diem   -   carpe diem