13 minute read

Chapter 2 • Built-in Data Structures

In the previous chapter, we installed Python 3 on various platforms. We wrote a simple introductory program and learned how to run it in various ways. We also learned how to work with the interpreter (interactive) mode. This chapter was introductory and was not very heavy on programming.

This chapter is a little bit more focused on programming (also known as coding). We will be introduced to various built-in data structures in Python. We will be focusing on the following topics in detail:

• IPython • List • Tuple • Set • Dictionary

Following this chapter, we will be comfortable with IPython and built-in data structures in Python.

2.1 IPython

IPython means Interactive Python Shell. It is a program that provides us with more facilities than python's built-in interactive shell. We have to install it separately using the following command:

pi@raspberrypi:~ $ pip3 install ipython

The command is the same for Windows and macOS. If you are installing it on a Linux distribution (like me), you may see the following message in the installation log:

The scripts iptest, iptest3, ipython, and ipython3 are installed in '/ home/pi/.local/bin' which is not on PATH.

Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location.

This means we need to add the mentioned directory location to ~/.bashrc and ~/.bash_ profile files. We have to add the following line to both the files (so it works for login and non-login shells):

PATH=$PATH:/home/pi/.local/bin

It will show a similar message for Windows too. We have to add the path of the directory mentioned in the installation log to the PATH variables (User and System variables, both) in Windows too.

Once we change the path, we have to close and re-invoke the command line utilities of the operating systems. After this, run the following command:

pi@raspberrypi:~$ ipython3

This will launch the IPython for Python 3 in the command prompt. The command is the same for Windows and other platforms. Figure 2-1 is the screenshot of an IPython session in progress on a Windows desktop computer:

Figure 2-1: IPython session in progress

We can use IPython like this to write small programs. So, let's roll.

2.2 Lists

We can store more than one value in lists. Lists are a built-in feature of Python. We do not have to install or import anything when using lists. List elements are enclosed in square brackets and separated by commas. But lists are in no way linear data structures as we can also have a list of lists. We will see more about the list of lists later when we are comfortable with the basics.

Lists are mutable, meaning we can change them. Let us see a few examples of lists and associated built-in routines for the same. Open IPython on the command prompt of your operating system and follow the code:

In [1]: fruits = ['babana', 'pineapple', 'orange']

This will create a list. Now, we can print it on the console in two ways:

In [2]: fruits

This produces the following output:

Out[2]: ['babana', 'pineapple', 'orange']

We can also use the built-in print function as follows:

In [3]: print(fruits)

The following is the output:

['banana', 'pineapple', 'orange']

A list is an ordered data structure, meaning that the members of the lists are stored and retrieved in a particular order. We can use this to our advantage to retrieve the elements of the lists. The very first element has an index of 0. If the size of the list is n, the last element is indexed as n-1. This is similar to the indices of an array in C, C++, and Java. If you have programmed before with these programming languages, you will find this scheme of indexing familiar.

We can retrieve the elements of the lists by using the combination of the name of the list and the index of the element. The following is an example:

In [4]: fruits[0] Out[4]: 'banana' In [5]: fruits[1] Out[5]: 'pineapple' In [6]: fruits[2] Out[6]: 'orange'

We can also use negative indices. -1 refers to the last element and -2 refers to the last but one element. The following is the example:

In [7]: fruits[-1] Out[7]: 'orange' In [8]: fruits[-2] Out[8]: 'pineapple'

If we try to use an invalid index, we see the following results:

In [9]: fruits[3]

IndexError Traceback (most recent call last) <ipython-input-9-7ceeafd384d7> in <module> ----> 1 fruits[3]

IndexError: list index out of range In [10]: fruits[-4]

IndexError Traceback (most recent call last)

<ipython-input-10-1cb2d66442ee> in <module> ----> 1 fruits[-4]

IndexError: list index out of range

We can retrieve the length of the list as follows:

In [12]: len(fruits) Out[12]: 3

We can also see the data type of the list as follows:

In [13]: type(fruits) Out[13]: list In [14]: print(type(fruits)) <class 'list'>

As we can see in the output, the class of the variable is list. We will learn about this in detail in the fourth chapter of this book.

We can use the constructor list() to create a list:

In [15]: fruits = list(('banana', 'pineapple', 'orange')) In [16]: fruits Out[16]: ['banana', 'pineapple', 'orange']

We can retrieve the range of the elements from the lists follows:

In [17]: SBC = ['Raspberry Pi', 'Orange Pi', 'Banana Pi', 'Banana Pro', 'NanoPi', 'Arduin ...: o Yun', 'Beaglebone'] In [18]: SBC[2:5] Out[18]: ['Banana Pi', 'Banana Pro', 'NanoPi']

In this example, we are retrieving the elements indexed with 2, 3, and 4. Also, consider the following example:

In [19]: SBC[2:] Out[19]: ['Banana Pi', 'Banana Pro', 'NanoPi', 'Arduino Yun', 'Beaglebone']

This way we can retrieve the elements from index 2 and onwards.

In [20]: SBC[:2] Out[20]: ['Raspberry Pi', 'Orange Pi']

And this way we can retrieve all elements before index 2. We can also use negative indices to retrieve multiple elements as follows:

In [21]: SBC[-4:-1] Out[21]: ['Banana Pro', 'NanoPi', 'Arduino Yun']

We can also use the if construct to check if an element exists in the list as follows:

In [23]: if 'Apple Pie' in SBC: ...: print('Found') ...: else: ...: print('Not Found') ...: Not Found

We can change an item in the list as follows:

In [25]: SBC[0] = 'RPi 4B 8GB'

We can also insert an item into a list at an index as follows:

In [36]: SBC.insert(2, 'Test Board')

The item at index 2 in this list is shifted one position forward. The same is true for the rest of the items.

We can append an item to the list as follows,

In [38]: SBC.append('Test Board 1')

This will add the item to the end of the list. We can also use extend operation with lists. This adds one list to the end of another list.

In [39]: list1 = [1, 2, 3]; list2 = [4, 5, 6]; In [40]: list1.extend(list2) In [41]: list1 Out[41]: [1, 2, 3, 4, 5, 6]

We can remove an item from the list as follows:

In [43]: SBC.remove('Test Board')

We can use two different approaches to remove the item at a specified index. Both the approaches are demonstrated below:

In [44]: SBC.pop(0) Out[44]: 'RPi 4B 8GB' In [46]: del SBC[0]

If we specify no index, it will pop (meaning remove and return) the last item:

In [47]: SBC.pop() Out[47]: 'Test Board 1'

We can remove all elements from the list as follows:

In [48]: SBC.clear()

We can also delete an entire list as follows,

In [49]: del SBC

If we try to access the list now, it will return an error as follows:

In [50]: SBC

NameError Traceback (most recent call last) <ipython-input-50-69ed78d7b4fc> in <module> ----> 1 SBC

NameError: name 'SBC' is not defined

We will now understand how to use the lists with loops. Create a list as follows:

In [51]: fruits = ['apple', 'banana', 'cherry', 'pineapple', 'watermelon', 'papaya']

We can use the for loop construct as follows,

In [52]: for member in fruits: ...: print(member) ...: apple banana cherry pineapple watermelon

papaya

The following code also produces the same result:

In [53]: for i in range(len(fruits)): ...: print(fruits[i]) ...: apple banana cherry pineapple watermelon

papaya

We can also use the while loop as follows:

In [54]: i = 0

In [55]: while i < len(fruits): ...: print(fruits[i]) ...: i = i + 1

...: apple banana cherry pineapple watermelon

papaya

Before proceeding further, I want to cover an important feature. We have worked with examples of many lists. Most of the lists we worked with are lists of character strings. A couple are lists of numbers. We can also have lists of other data types. The following are examples:

In [56]: l1 = [1.2, 2.3, 3.4]

In [57]: l2 = ['a', 'b', 'c']

In [58]: l3 = [True, False, False, True, True, False]

Here we created lists of floats, characters, and Boolean values respectively. We can also create a list of mixed types as follows:

In [59]: l4 = [1, 'Test', 'a', 1.2, True, False]

We can sort a list as follows:

In [60]: fruits.sort() In [61]: fruits Out[61]: ['apple', 'banana', 'cherry', 'papaya', 'pineapple', 'watermelon']

We can also sort a list in reverse order as follows:

In [62]: fruits.sort(reverse = True) In [63]: fruits Out[63]: ['watermelon', 'pineapple', 'papaya', 'cherry', 'banana', 'apple']

As an exercise, sort numeric and boolean lists.

We can copy a list into another as follows:

In [64]: newlist = fruits.copy()

We saw earlier that the routine extend() can join two lists. We can use the addition (+) operator to join two lists as follows:

In [65]: l1 + l2 Out[65]: [1.2, 2.3, 3.4, 'a', 'b', 'c']

We can use the multiplication operator with lists as follows,

In [66]: l1 * 3 Out[66]: [1.2, 2.3, 3.4, 1.2, 2.3, 3.4, 1.2, 2.3, 3.4]

2.3 Tuples

Tuples are similar to lists. We have to use brackets while creating them. Their difference with lists is that they are immutable, meaning once they are created, they cannot be modified. Let's see a simple example as follows,

In [1]: fruits = ('apple', 'grape', 'mango') In [2]: fruits Out[2]: ('apple', 'grape', 'mango') In [3]: print(type(fruits)) <class 'tuple'>

The indexing, looping, and concatenation (the + operator) for tuples are the same as lists. As tuples are immutable, we cannot directly change any information stored in the tuples. However, we can convert them to lists and then assign the changed list to any tuple. See the following example:

In [4]: temp_list = list(fruits)

In [5]: temp_list.append('papaya')

In [6]: fruits = tuple(temp_list)

In [7]: fruits Out[7]: ('apple', 'grape', 'mango', 'papaya')

In the example above, we demonstrated the usage of the routine tuple(). This way, we can use all the routines of lists cleverly to work with tuples. Let's see the demonstration of the method count() to count how many times a particular member element occurs in the tuple:

In [8]: test_tuple = (2, 3, 1, 3, 1, 4, 5, 6, 3, 6) In [9]: x = test_tuple.count(3) In [10]: print(x) 3

2.4 Sets

Lists and tuples are ordered data structures and both allow duplicate values. Sets are different than both as they are unordered and hence do not allow duplicate values. Sets are defined using curly brackets. The following is an example of simple sets:

In [12]: set1 = {'apple', 'banana', 'orange'} In [13]: set1 Out[13]: {'apple', 'banana', 'orange'} In [14]: set2 = set(('apple', 'banana', 'orange')) In [15]: set2 Out[15]: {'apple', 'banana', 'orange'} In [16]: print(type(set1)) <class 'set'>

We cannot use indexes to retrieve the elements of any set, as sets are unordered. But we can use loop constructs for and while. Try this as an exercise. We can add new items with the routine add() as follows:

In [17]: set1 Out[17]: {'apple', 'banana', 'orange'} In [18]: set1.add('pineapple') In [19]: set1 Out[19]: {'apple', 'banana', 'orange', 'pineapple'}

We can use the routines remove() or discard() to remove an item from any list as follows:

In [20]: set1.remove('banana') In [21]: set1.discard('apple')

Both the routines raise errors if we try to remove non-existent items. Let's see a few set methods. First, we will see how to compute the union of two sets. Let's create sets for this:

In [22]: set1 = {1, 2, 3, 4, 5} In [23]: set2 = {3, 4, 5, 6, 7} In [24]: set3 = set1.union(set2) In [25]: set3 Out[25]: {1, 2, 3, 4, 5, 6, 7}

Here, we store the union in a new set. A slight alternate approach stores the union in the first set as follows,

In [29]: set1.update(set2) In [30]: set1 Out[30]: {1, 2, 3, 4, 5, 6, 7}

We can also remove all elements in a set as follows:

In [31]: set3.clear()

The routine copy() works in the similar way to list. Let's compute the difference as follows:

In [32]: set3 = set1.difference(set2) In [33]: set3 Out[33]: {1, 2}

This example returns a new output set. We can remove the matching elements from one of the sets using this:

In [34]: set1.difference_update(set2) In [35]: set1 Out[35]: {1, 2}

We can compute intersection as follows:

In [37]: set3 = set1.intersection(set2) In [38]: set3 Out[38]: {3, 4, 5}

We can check if a set is a subset of another set as follows:

In [39]: set2 = {1, 2, 3, 4, 5, 6, 7, 8} In [40]: set1.issubset(set2) Out[40]: True

Similarly, we can check if a set is a superset of another set:

In [41]: set2.issuperset(set1) Out[41]: True

We can also check if two sets are disjoint (do not have any common elements) as follows:

In [42]: set1 = {1, 2, 3} In [43]: set2 = {4, 5, 6} In [44]: set1.isdisjoint(set2) Out[44]: True

We can compute the symmetric difference between two sets as follows:

In [45]: set1 = {1, 2, 3} In [46]: set2 = {2, 3, 4} In [47]: set3 = set1.symmetric_difference(set2) In [48]: set3 Out[48]: {1, 4}

We can also compute union and intersection with operators | and s as follows:

In [49]: set1 | set2 Out[49]: {1, 2, 3, 4} In [50]: set1 & set2 Out[50]: {2, 3}

2.5 Dictionaries

Dictionaries are ordered, changeable, and do not allow duplicates. Dictionaries in Python 3.6 are unordered. Dictionaries from Python 3.7 are ordered. The items are stored in dictionary in key:value pairs and can be referred to by using the name of the key. Let's create a simple dictionary as follows:

In [52]: test_dict = { "fruit": "mango", "colors": ["red", "green", "yellow"]}

We can access the items of the dictionary using the keys as follows:

In [53]: test_dict["fruit"] Out[53]: 'mango'

In [54]: test_dict["colors"] Out[54]: ['red', 'green', 'yellow']

We can retrieve keys and values as follows:

In [55]: test_dict.keys() Out[55]: dict_keys(['fruit', 'colors'])

In [56]: test_dict.values() Out[56]: dict_values(['mango', ['red', 'green', 'yellow']])

We can update a value as follows:

In [60]: test_dict.update({"fruit": "grapes"}) In [61]: test_dict Out[61]: {'fruit': 'grapes', 'colors': ['red', 'green', 'yellow']}

We can add into the dictionary as follows:

In [62]: test_dict["taste"] = ["sweet", "sour"] In [63]: test_dict Out[63]: {'fruit': 'grapes', 'colors': ['red', 'green', 'yellow'], 'taste': ['sweet', 'sour']}

We can also pop items:

In [64]: test_dict.pop("colors") Out[64]: ['red', 'green', 'yellow'] In [65]: test_dict Out[65]: {'fruit': 'grapes', 'taste': ['sweet', 'sour']}

We can also pop the last inserted item:

In [66]: test_dict.popitem() Out[66]: ('taste', ['sweet', 'sour'])

We can also delete an item,

In [67]: del test_dict["fruit"] In [68]: test_dict Out[68]: {}

We can also delete a dictionary as follows:

In [69]: del test_dict In [70]: test_dict

NameError Traceback (most recent call last) <ipython-input-70-6651ddf27d40> in <module> ----> 1 test_dict

NameError: name 'test_dict' is not defined

We can loop through dictionaries using for and while loop constructs. Try doing this as an exercise.

Summary

In this chapter, we learned the basics of sets, tuples, lists, and dictionaries in Python. Together, these are known as collections in Python.

In the next chapter, we will learn the basics of strings, functions, and recursion.

This article is from: