Another 3 Python concepts that imply proficiency

Orestis Zekai
Geek Culture
Published in
4 min readAug 17, 2022
Magnifying glass

In the previous article we took a closer look at some python concepts that prove expertise in the language and will help you advance in your career. The feedback I got made me realize that lots of individuals found it useful, which led to the article you are reading. Here, we will discuss another 3 python concepts that demonstrate proficiency in it.

💭 Comprehensions

Comprehensions are a quick and compact way of creating sequences from other sequences. As a sequence we consider anything that can be iterated. This includes lists, dictionaries, sets, generators etc. This may sound vague, but everything will become clearer with an example. Let’s assume that we have a list of numbers and we want to create another list that contains the number of the original list to the power of 2. The traditional way to do it would be the following:

my_list = [1, 2, 3, 4, 5] 
pow_of_2 = []
for number in my_list:
pow_of_2.append(number * number)

We have the usual for loop that we iterate over the original list and we append the newly calculated number every time. The way to do it with a comprehension is the following:

pow_of_2 = [number * number for number in my_list] 

As you can see, using comprehensions is similar to talking. If we were to read the expression above, it would be “create a list that contains the number times itself for every number in the sequence”. This applies not only for lists, but for any sequence. For example dictionaries:

pow_of_2_dict = { number: number * number for number in my_list }

What is the benefit? For starters, using comprehensions is quite telling. You can easily understand what it does without reading through lines of code. Also, one can argue that comprehensions are faster than traditional loops but this is a topic for some other time (if you are interested, this SO answer gives you a nice overview)

📦 Unpacking

Unpacking is an operation in Python that consists of assigning an sequence of values to an iterable in a single assignment statement. In the early days, the sequence used was tuples, but a lot of Python developers have been using it and it has been generalized to many sequences. The above may sound a bit confusing at first, but an example will make it all clear.

Let’s imagine that we have a single function to find the minimum and the maximum number in a list of integers. This function does more than one thing, so you should not encounter it in the wild. We just use it here as an example:

def find_min_max():
return min(my_list), max(my_list)

This may not make much sense (returning 2 arguments), but in Python, you can call this function using this expression:

list_min, list_max = find_min_max()

Now, these 2 variables contain the values needed and the assignment was done in one line. This little trick makes our code easier to read, maintain and extend. If we do not need for example the minimum value, we can use a throwaway variable. But this is maybe for a next article.

What we need to be really careful of in this tool, is that the variables match. The return values need to be the same number as the values waiting on the other side of the expression. If this is not the case, Python will throw a ValueError .

Bonus: There is reference to a list in the function, but we are not passing any arguments. Curious to find out why? Click here!

📋 Dataclasses

Introducing in standard Python with the version 3.7, dataclass is a module used to create classes, mainly for storing and manipulating data in them. It comes with a set of functions that make working with data classes easier. Of course, you can use dataclasses with earlier Python versions, but you need to install it manually.

The way to declare classes by using the dataclass module, is by utilizing decorators:

from dataclasses import dataclass
from typing import Optional
@dataclass
def Car:
plate_number: str
colour: Optional[str] = None

This is all we need to do. Now we can use this class to create objects:

my_car = Car("ABC 1234")

What one might ask, is “Where is the __init__() method?”. The dataclass makes sure to assign the corresponding parameters to the correct variables. It takes care of data types and default values as well.

After initializing the object, you can easily access its attributes:

>>> my_car.plate_number
"ABC 1234"

Besides the __init__() method, the __eq__() and __repr__() methods work different.

The __eq__() method is used to check the equality between objects. By default, different objects are stored in different memory spaces, hence this method will return False when comparing objects of the same class, even if they hold the same data. But this is not true with dataclasses. Since they are used to store data, this method returns Trueif all data in the object is equal.

The __repr__() method is used to manipulate what is shown when the class object is printed. In regular classes, if we print an instance, we usually get something like <Class.Class object at 0x868df81> . With dataclasses, we get a more telling message. In the example above, we would get:

>>> print(my_car)
Car(plate_number="ABC 1234", colour=None)

As stated in my last article, this was just a glimpse of what Python can offer. If you really want to master it, you will need to devote time and for sure, you will be rewarded.

--

--