Lists

Lists are the first compound data type that will be presented to you on this site. They are a very popular way of organizing values. Lists, same as with strings, can be indexed and sliced.

When you request the index of the list, python will always return back a list when it matches more than one value! This can play a role in how these lists can be used to extract subset of information. As with strings you can request a slice of the list using the : moniker.

An important concept to understand when looking at Python lists and slices is to understand that indexes represent a position in the list. While a slice represents the distance from the start or the end of the list.

Using the Python interpreter below run a series of exercises that will help you see the difference between index and slices. This functionality is critical to understand as these will be used heavily when working with object returns in ACI in the future.


>>> letters=["a","b","c","d","e","f","g"]
>>> print letters[4]
e

>>> letters=["a","b","c","d","e","f","g"]
>>> print letters[:3]
['a', 'b', 'c']
>>> print letters[4:]
['e', 'f', 'g']
        
Exercise
letters=["a","b","c","d","e","f","g"]
Print out the letters 3 through 5 of the list
Print the letters from the start of the list to the position -3 of the list
Console 1

                
            

Lists can also be concatenated just as you had done with strings. By using the + operator you can add to a list.

You can also utilize the append() method to add values at the end of the list


>>> letters=["a","b","c","d","e","f","g"]
>>> letters = letters + ["h","i"]
>>> print letters
['a', 'b', 'c', 'd', 'e', 'f', 'g', 'j', 'h', 'i']
>>> letters.append("j")
>>> print letters
['a', 'b', 'c', 'd', 'e', 'f', 'g', 'j', 'h', 'i', 'j']
        

Lists are also mutable ( remember that strings aren't). This makes it possible to change the value of a list by referencing the index.


>>> letters = ["a","b","c","z","e","f","g"]
>>> print "Z doesn't go there"
Z doesn't go there
>>> letters[3]="d"
>>> print letters
['a', 'b', 'c', 'd', 'e', 'f', 'g']
        

It is possible to use a slice to insert changes into the list. Or you can utilize the slice function to remove sections of the list or clear the entire list. You can reference the following diagram again to remember the index and slicing marks.


>>> letters=["a","b","c","d","e","f","g"]
>>> letters[3:3]=["x","y","z"]
>>> print letters
['a', 'b', 'c', 'x', 'y', 'z', 'd', 'e', 'f', 'g']
>>> letters[3:5]=[]
>>> print letters
['a', 'b', 'c', 'z', 'd', 'e', 'f', 'g']
>>> letters[:]=[]
>>> print letters
[]
        
Exercise
letters=["a","b","c","d","e","f","g"]
Insert three letters substituting the letter d in the list
Remove the letters b and c from the list.
Console 2

                
            

Nested Lists

Nested lists make it possible to create what sometimes are referred as multi dimensional arrays. These nested lists make is possible to do some nifty tricks in storing information and retrieving when one knows the structure around the lists.

Look at the following nested list:

If you wanted to access that list and reference a value in one of those lists you now have to first include the reference. So if you did print list[0][1] you would get the letter b.

If you look at the following diagram we can see that these lists can start to be useful when doing programing around networking.

Such a list could be useful to contain a list of interface properties that could be used to code a long list of interfaces in a router or switch.

Using this example we can refer to the nested lists to extract values. In this example we have three lists that are nested inside one list. To extract the IP address of the second line on the list we just do the command print test[1][1]


>>> test=[  ["eth1/1","10.1.1.1","255.255.255.0"],
            ["eth1/2","10.1.2.1","255.255.255.0"],
            ["eth1/3","10.1.3.1","255.255.255.0"]]
>>> print test[1][1]
10.1.2.1
        

Using the same logic we could create a string that is the configuration of a interface.


>>> inters=[ ["eth1/1","10.1.1.1","255.255.255.0"],
             ["eth1/2","10.1.2.1","255.255.255.0"],
             ["eth1/3","10.1.3.1","255.255.255.0"]]
>>> print "interface %s \n ip address %s %s" % \
( inters[0][0], inters[0][1],inters[0][2] )

interface eth1/1
 ip address 10.1.1.1 255.255.255.0
        

Sorting Lists

In Python it's possible to sort a list with the built-in sort function. To understand what a built-in function is you have to think that the list that we have built is actually a Python object. And that object has properties and functions that are associated to them. A list has varios functions including sort, append, insert and others that we have seen during this chapter. Python also has a separate sorted() function that can be used to sort that list.

It is important to remember that while the list object has these functions, it doesn't mean that other objects like dictionaries have the same functions.

Another important note is that for sort to work properly the default key has to be all of the same type. You can have a list that contains digits and letters and expect Python to sort these.


>>> sortlist = [ 6 , 1 , 5 , 8, 9, 3, 6]
>>> sortlist.sort()
>>> print sortlist
[1, 3, 5, 6, 6, 8, 9]

>>> sortlist = [ 6 , 1 , 5 , 8, 9, 3, 6]
>>> print sorted(sortlist)
[1, 3, 5, 6, 6, 8, 9]

Sumarizing List operations

Operation Description Example
[] Create Empty List list = []
append(object) Append to end of list list.append("car")
insert(index , object) Insert into the list at specific location list.insert(3, "car")
del(list[0]) Delete from list at specific index or slice del(list[0])
remove(value) Search and delete value from list in place list.remove("car")
sort() Sorts a list list.sort()
reverse() Reverses a list list.reverse()

Tuples

Tuples are almost identical to lists with one exception. They are immutable. What that means is that once the tuple is created it can't be modified. The different between a Tuple and a list is during the creation of the tuple.

tuple_example = ( 1 , 2 , 3 , 4 , 5 , 6 )

After the tuple is created then it is treated the same way as you would a list.


>>> tuple_example = ( 1, 2, 3, 4, 5, 6 )
>>> print tuple_example[3]
4

You can concatenate tuples the same way as lists with the + or you can also utilize the multiplier *.


>>> tuplelist = ( 1, 2, 3, 4, 5, 6, 7)
>>> 2 * tuplelist
(1, 2, 3, 4, 5, 6, 7, 1, 2, 3, 4, 5, 6, 7)

Python permits tuples in the left hand side of the operator which can reduce coding. For example if you wanted to have 4 variables with different values you could code this in as:

eth1 = 10.1.1.1
eht2 = 10.1.2.1
eht3 = 10.1.3.1

Using tuples you could simplify this into a single line of python code as:

(eth1, eth2, eth3) = ("10.1.1.1", "10.1.2.1","10.1.3.1")

>>> (eth1, eth2, eth3) = ("10.1.1.1", "10.1.2.1","10.1.3.1")
>>> eth1
'10.1.1.1'

Dictionaries

In python there is another complex data structure called a Dictionrary. Dictionaries are similar to lists, but instead of having the index be referred by number you can index based on names that you choose. These can be numbers, strings, letters or symbols and the advantage is that this reference can be used for many neat tricks.

When you where working with lists you utilized the numeric index. With dictionaries you can utilize the name you specified for the index. This mechanism makes reading code and working with code so much easier. For example it is easier to reference the defect as defect["id"] instead of saying defect[0].


    >>> defect = {  "id" : "CSCdk12345",
                    "title" : "Router Crash",
                    "prod" : "asr1k"}
    >>> print defect["id"]
    CSCdk12345
    >>> output = "The defect with id {0} has the title {1}".format(defect["id"], defect["title"])
    >>> print output
    The defect with id CSCdk12345 has the title Router Crash
    

Dictionaries can also be nested as you had done with lists previously. This nesting makes it possible to build very powerful data structures. Using the same example we just showed, you can have multiple defect definitions inside the same data structure.


>>> defects = { "CSCdk12345": { "id":"CSCdk12345",
                                "title":"Router Crash",
                                "prod":"asr1k"},
                "CSCdk98765": { "id":"CSCdk98765",
                                "title":"Memory Error",
                                "prod":"nexus9k"}}
>>> print "The defect {0} is part of the {1} product family".format(defects["CSCdk12345"]["id"],defects["CSCdk12345"]["prod"])
The defect CSCdk12345 is part of the asr1k product family
    

You can also create a list of dictionary entries.


>>> defects = [ {   "id":"CSCdk12345",
                    "title":"Router Crash",
                    "prod":"asr1k" } ,
                {   "id":"CSCdk98765",
                    "title":"Memory Error",
                    "prod":"nexus9k"}]
>>> print "The defect {0} is part of the {1} product family".format(defects[0]["id"],defects[0]["prod"])
The defect CSCdk12345 is part of the asr1k product family
    

Dictionaries are also objects and because of that have methods that can be used.


dict = {"eth1/1":"1.1.1.1","eth1/2":"1.1.1.2","eth1/3":"1.1.1.3"}
method Result
print dict {'eth1/1': '1.1.1.1', 'eth1/3': '1.1.1.3', 'eth1/2': '1.1.1.2'}
print dict.items() [('eth1/1', '1.1.1.1'), ('eth1/3', '1.1.1.3'), ('eth1/2', '1.1.1.2')]
print dict.values() ['1.1.1.1', '1.1.1.3', '1.1.1.2']
print dict.keys() ['eth1/1', 'eth1/3', 'eth1/2']

The real value of lists and dictionaries are going to show more prominently when you look at iterating through a list. If you wanted to build the configuration of 10 interfaces and had all the values required for these interface configurations in a list or dictionary then you could iterate through that list and create the configuration with a simple code loop. We will start looking at programing structures in the next section.