/ 100DaysOfPython

Day 7: Collections in Python

A recap of Lists in Python

We've already looked at lists in the previous post. Let's quickly go over what they are again.


This post is part of #100DaysOfPython, check out yesterday's post here if you haven't already. Or go to the index of all 100 days.


A list allows us to store more than a single value in Python under the same variable. Then we can access particular elements of the list or iterate over the list's elements.

To access a particular element, we use the index notation: e.g. my_list[0].

To iterate over a list, we use a for loop. The variable takes the value of each of the elements of the list:

my_list = ['hello', 'world']

for e in my_list:
    print(e)

Would print:

hello
world

Lists and Tuples

Another data structure that is frequently mentioned in Python is the tuple. A tuple is the same as a list, but it cannot be modified.

The syntax for a tuple is the following:

my_tuple = ('hello', 'world')

In Python you can frequently skip the brackets when creating a tuple, although it is highly discouraged; as you can only do so in some circumstances.

Whereas we can add or remove elements from a list, we cannot do so from a tuple.

Similarly, we cannot replace an element in a tuple for another element. Thus, while the following operations are allowed in a list, they are not allowed in a tuple:

my_list = ['hello', 'world']

my_list.append('my name is')
my_list.remove('hello')
my_list[1] = 'Hello'

my_tuple = ('hello', 'world')

my_tuple.append('my name is')  # Raises an error
my_tuple.remove('hello')  # Raises an error
my_tuple[1] = 'Hello'  # Raises an error

However, for all other intents and purposes, tuples and lists are very similar. You can access particular elements using the index notation, and you can also iterate over the tuples' elements using a for loop.

List and Tuple methods

To further illustrate the differences between lists and tuples, look at the methods that are available in each one:

Lists

my_list.append(...)
my_list.count(...)
my_list.insert(...)
my_list.reverse(...)
my_list.clear(...)
my_list.extend(...)
my_list.pop(...)
my_list.sort(...)
my_list.copy(...)
my_list.index(...)
my_list.remove(...) 

Tuples

my_tuple.count(...)
my_tuple.index(...)

Even if it's not clear what each one of the methods does, note how any of the methods that could potentially modify the tuple are just not there. We only have access to methods that give us a count and an index.

The official Python documentation has more info on what each of these methods does, if you're interested!

Sets

Sets are another type of collection—which means each contains multiple values—but they are governed by different constraints:

  • You cannot have duplicate elements in a set; and
  • Sets are not ordered.

The syntax for a set is the following:

my_set = {1, 3, 5, 7, 9}

If we try to ignore the constraint and place duplicate elements within a set, that's fine. They just get dropped:

my_set = {1, 3, 3, 3, 5, 7, 9}

print(my_set)  # {1, 3, 5, 7, 9}

There's no way to sort a set. Whenever we print a set or otherwise use it, the elements may or may not be in the same position as the last time we used it.

However, if we really need to display the sorted results, we can turn the set into a list and sort that:

my_set = {3, 5, 1, 7, 6, 2}

sorted_values = sorted(list(my_set))
print(sorted_values)  # [1, 2, 3, 5, 6, 7]

Why use sets?

The constraints placed allow us to run a few powerful operations. Since we don't have duplicates or sorting, it becomes effortless to check which unique elements are in one set but not another; simply by subtracting them:

names = {'Jose', 'Rolf', 'Bob', 'Jack'}

fake_names = {'Rolf', 'Bob'}

print(names - fake_names)  # {'Jose', 'Jack'}

We can also check which elements are in both sets; discarding those numbers which are not in both:

lottery_numbers = {1, 33, 44, 2, 17}

my_numbers = {14, 15, 16, 17, 33}

print(lottery_numbers & my_numbers)  # {17, 33}

We can also create a set which contains two sets added together; naturally without duplicates:

my_friends = {'Jack', 'Anne'}

your_friends = {'Bob', 'Jack', 'Michael'}

our_friends = my_friends | your_friends
print(our_friends)  # {'Jack', 'Bob', 'Anne', 'Michael'}

To learn more about set operations, the official Python documentation has a lot of info.

Dictionaries

A dictionary is very similar to a set, except instead of storing single values like numbers or strings, it associates those values to something else. This is normally a key-value pair.

For example, we could create a dictionary that associates each of our friends' names with a number describing how long ago we last saw them:

my_friends = {
    'Jose': 6,
    'Rolf': 12,
    'Anne': 6
}

The same constraints as sets apply, but only on the keys. You cannot have duplicate keys, and the keys are not ordered. The values can be duplicated as many times as you want.

However, you cannot add or subtract dictionaries like you can do with sets.

Dictionary iteration

At times it may be useful to iterate over a dictionary's keys and values—such as if we want to print out our friend names and how long since we last saw them:

my_friends = {
    'Jose': 6,
    'Rolf': 12,
    'Anne': 6
}

for key, value in my_friends.items():
    print(f'I last saw {key} {value} days ago.')

Don't know what that f in front of the string is? Check out our post on String formatting.

List comprehension

At times we may want to use the values of a list to create a new list with related values. For example, say you have a list of days and you want to calculate how many weeks each day is.

You could do this:

day_group = [4, 7, 14, 16, 28]
weeks = []

for days in day_group:
    weeks.append(days / 7.0)  # 7.0 so Python doesn't do integer division!

print(weeks)  # [0.5714285714285714, 1.0, 2.0, 2.2857142857142856, 4.0]

By using list comprehension, we can make this both more readable and shorter.

List comprehension always has the following structure:

[expr for value in sequence]

Notice the similarity of the list comprehension with the for loop. You've got a for loop in there!

Every iteration over the sequence's values gives you a value variable. You can use this variable inside the expr part of the list comprehension.

For example, going back to our days and weeks:

day_groups = [4, 7, 14, 16, 28]
weeks = [days/7.0 for days in day_groups]

print(weeks)  # [0.5714285714285714, 1.0, 2.0, 2.2857142857142856, 4.0]

We can also add a conditional to a list comprehension, so that the expr is only evaluated if the conditional is True:

day_groups = [4, 7, 14, 16, 28]
weeks = [days/7.0 for days in day_groups if days % 7 == 0]

print(weeks)  # [1.0, 2.0, 4.0]

Set comprehension

Just like we can do list comprehension to generate a new list from another sequence, we can do set comprehension.

It's exactly the same, except we end up with a set instead of a list. Check out the below program to calculate how many different starting letters our group of friends has:

my_friends = ['Jose', 'Jack', 'Rolf', 'Joanne']

starting_letters = {name[0] for name in my_friends}

print(len(starting_letters))  # 2

Think about how you would write the above snippet without using sets! Not so easy, huh?


In this post we've looked at some of the fundamental collections in Python: lists, tuples, sets, and dictionaries. It's essential that you know what these are and how to use them, as they'll appear over and over again when you are programming.

In addition, understanding that you have more tools than just lists will allow you to use each to their strengths when you need to!

In a future post we'll look at more advance usage of these collections, and some other collections that are available.

I'll see you on the next one!

Like what you see?

Join our e-mail list to receive new content as it's posted—once or twice a month!