Tuples
A tuple is a collection of ordered objects separated by commas. In some aspects, it works similar to a list, supporting slice indexing, nested objects, and iteration. Nevertheless, unlike a list, a tuple is immutable, meaning that you cannot modify it once created. So, tuples are not as flexible as Python lists.
However, tuples exhibit better memory efficiency compared to lists. This is because Python can precisely allocate the required memory size for a tuple during creation, resulting in a more compact memory arrangement. Unlike lists, tuples do not pose concerns related to dynamic growth or alterations in data types, contributing to their streamlined memory utilization.
To create a tuple, you should put items inside parentheses, as follows:
my_tuple = ("a", "b", "c")
print(my_tuple)
## ('a', 'b', 'c')
print(type(my_tuple))
## <class 'tuple'>
You can then access elements in a tuple with their associated indices:
print(my_tuple[0])
## a
print(my_tuple[0:1])
## ('a',)
print(my_tuple[1:])
## ('b', 'c')
print(my_tuple[-1])
## c
print(my_tuple[-1:])
## ('c',)
An alternative way to create a tuple is:
my_tuple2 = "d", "e", "f"
print(my_tuple2)
## ('d', 'e', 'f')
print(type(my_tuple2))
## <class 'tuple'>
This is called tuple packing, which assigns items on
the right-hand side of the assignment operator =
to a
single variable on the left-hand side. Conversely, to assign each item
inside a tuple on the right-hand side to multiple variables on the
left-hand side is called tuple unpacking. For
example:
first, second, third = my_tuple2
print(first)
## d
print(second)
## e
print(third)
## f
When unpacking a tuple, the number of items inside the tuple and the number of variables on the left-hand side must match. Otherwise, Python will throw an error. For example:
my_variable1, my_variable2 = my_tuple
## ValueError: too many values to unpack (expected 2)
You may use an asterisk (*
) to capture remaining
elements. This is useful when you cannot pre-determine the number of
elements a tuple contains. Depending on where you put the *
sign, Python will assign whichever leftover items to the variable as a
list.
pi, e, *parameters = 3.14, 2.72, "mu", "sigma"
print(pi)
## 3.14
print(e)
## 2.72
print(parameters)
## ['mu', 'sigma']
print(type(parameters))
## <class 'list'>
pi, *parameters, e = 3.14, "mu", "sigma", 2.72
print(pi)
## 3.14
print(e)
## 2.72
print(parameters)
## ['mu', 'sigma']
Sets
In Python, a set is a mutable data.
Created by a pair of curly braces {}
, it behaves similar to
mathematical sets, meaning:
- Sets are unordered.
- Set elements are unique. Duplicate elements are not allowed.
While the set itself is mutable, to ensure the uniqueness of the elements, you cannot contain any mutable elements; every element contained in the set must be of an immutable type.
my_set = {'a', 'b', 'c'}
print(my_set)
## {'c', 'a', 'b'}
print(type(my_set))
## <class 'set'>
my_set.add(['a', 'b']) # Method to add a set element
## TypeError: unhashable type: 'list'
It is a mutable data type, so you can add or remove elements from a set even after it has been created.
The set constructor set()
also creates a set object, by
passing any iterable object into it. As mentioned, a set can
contain only unique values. Even if you pass a list having
duplicate elements into the set constructor, the resulting set will
contain only the unique items.
my_set2 = set([1, 2, 3])
print(type(my_set2))
## <class 'set'>
my_list = [1, 1, 2, 3]
print(set(my_list))
## {1, 2, 3}
This behavior is often useful. For example, one of the common tasks in daily Python programming is to remove duplicates from a list. Since you can convert a list with duplicated items to a set and then back again, this becomes pretty easy.
duplicated_list = ['apple', 'apple', 'banana', 'cherry', 'banana']
unique_list = list(set(duplicated_list))
print(unique_list)
## ['apple', 'cherry', 'banana']
Note that python sets aren’t ordered data structures. They’re more like big bags of elements all jumbled up. Keep that in mind when you use this trick to de-duplicate lists because applying the set constructor will randomize any orders in the original list. the order of elements in your list may not be the same coming back out.
Since it is not ordered, you can’t fetch elements by their indices.
my_set2[0]
## TypeError: 'set' object is not subscriptable
However, you can add elements to a set as below. Notice that this is different than the append function in the list, which specifically appends the element to the end of the list. Set uses the add function, which is kind of like tossing the element onto the pile without any order.
my_set2.add('D')
my_set2
## {1, 2, 3, 'D'}
Also, like with lists, you can use the membership operator
in
or not in
or len
function to
check the number of elements in a set.
'D' in my_set2
## True
len(my_set2)
## 4
Somewhat confusingly, however, set does have a pop function. It pops up an element from the set and removes. Of course, unlike with lists, you are not going to get an element from the end of the set.
my_set2.pop()
## 1
my_set2
## {2, 3, 'D'}
If you want to remove a specific element, you can do that by
.discard()
.
my_set2.discard('D')
my_set2
## {2, 3}
It’s also worth mentioning that sets can be very useful for
performing mathematical operations like union, intersection, and
difference. For example, you can use the |
operator to get
the union of two sets, the &
operator to get the
intersection, and the -
operator to get the difference.
Here’s an example:
set1 = {1, 2, 3, 4}
set2 = {3, 4, 5, 6}
union_set = set1 | set2
intersection_set = set1 & set2
difference_set = set1 - set2
print(union_set)
## {1, 2, 3, 4, 5, 6}
print(intersection_set)
## {3, 4}
print(difference_set)
## {1, 2}
These operations can be very useful for working with data and finding commonalities or differences between sets of values.
Dictionaries
In Python, Dictionaries are mutable and unordered data structures. They contain items without an order. Instead, they have key-mapping pairs to refer items, key:value. One important thing to note here is that keys in dictionary should have a unique value; no duplicate is allowed. Also, you cannot use any mutable objects for key. That is, you cannot use list, dictionary, or set as a key of a dictionary.
To create a dictionary:
pokemon = {
"ash": ["pikachu"],
"gary": "eevee",
}
pokemon
## {'ash': ['pikachu'], 'gary': 'eevee'}
type(pokemon)
## <class 'dict'>
You can have an access to each item by referencing key value:
pokemon["ash"]
## ['pikachu']
Since dictionaries are mutable, you can also replace an item:
print(pokemon["gary"])
## eevee
pokemon["gary"] = "jolteon"
print(pokemon["gary"])
## jolteon
To obtain keys and their mapping values, you can use
.keys()
and .values()
. Notice that this is a
dict_keys and dict_values object,
not a list.
It looks and behaviors like a list though. You can iterate over dict keys. However, unlike lists, they are immutable. You can’t change them directly, you just add to them.
pokemon.keys()
## dict_keys(['ash', 'gary'])
pokemon.values()
## dict_values([['pikachu'], 'jolteon'])
To add a new key-mapping relationship to a dictionary, you can do that as below.
pokemon['team rocket'] = ['meowth']
pokemon
## {'ash': ['pikachu'], 'gary': 'jolteon', 'team rocket': ['meowth']}
You can also add a new item to a list values inside a dictionary.
pokemon['team rocket'].append('arbok')
pokemon
## {'ash': ['pikachu'], 'gary': 'jolteon', 'team rocket': ['meowth', 'arbok']}
if 'dr.oak' not in pokemon:
pokemon['dr.oak'] = []
pokemon['dr.oak'].append('tauros')
pokemon
## {'ash': ['pikachu'], 'gary': 'jolteon', 'team rocket': ['meowth', 'arbok'], 'dr.oak': ['tauros']}
Like strings and lists, you can use the len()
function
on the dictionary. It will return the number of keys in the
dictionary.
len(pokemon)
## 4
Dictionary Comprehensions
Dictionary comprehensions are a concise way to create dictionaries from iterable objects. A dictionary comprehension generates a new dictionary with the specified key-value pairs. For example:
animals_list = [("a", "aardvark"), ("b", "bear"), ("c", "cat"), ("d", "dog")]
animals = {item[0]:item[1] for item in animals_list}
print(animals)
## {'a': 'aardvark', 'b': 'bear', 'c': 'cat', 'd': 'dog'}
In this example, we create a dictionary named animals
by
iterating over the tuples in animals_list
and using the
first item in each tuple as the key and the second item as the value.
The result is
{'a': 'aardvark', 'b': 'bear', 'c': 'cat', 'd': 'dog'}
.
The syntax for a dictionary comprehension is similar to that of a list comprehension, but with a key-value pair separated by a colon instead of just a single item. The comprehension is surrounded by curly braces instead of square brackets.
animals2 = {key:value for key, value in animals_list}
print(animals2)
## {'a': 'aardvark', 'b': 'bear', 'c': 'cat', 'd': 'dog'}
We can also convert the dictionary back into a list of tuples using
the items()
method, which returns a dict_items
object containing a list of key-value pairs:
list(animals.items())
## [('a', 'aardvark'), ('b', 'bear'), ('c', 'cat'), ('d', 'dog')]
If we want to transform each item in our list into a structure different from the original one, we can use a list comprehension. For example:
[{"letter":key, "name":value} for key, value in animals.items()]
## [{'letter': 'a', 'name': 'aardvark'}, {'letter': 'b', 'name': 'bear'}, {'letter': 'c', 'name': 'cat'}, {'letter': 'd', 'name': 'dog'}]
This comprehension creates a list of dictionaries with each
dictionary having the keys “letter” and “name” and the corresponding
values from the animals
dictionary.