Tuples, Sets, and Dictionaries

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.

Post a Comment

0 Comments