Check out these lesser-known Python features

Check out these lesser-known Python features
Credit: Unsplash

When I learn about a new feature in Python or I notice that a few others are unaware of that feature, I make a note of it.

Over the last few weeks, there have been a few interesting features that I myself recently learned about.

Here is a quick look at these features, and a rundown of each.

[Read: A look at the best new features in Python 3.9]

divmod

This is a very useful function. The divmod() function performs a modulus division % on two numbers, then returns both the quotient and remainder. For example:

divmod(5, 2)

[Out]: (2, 1)

This is simply finding the number of times we can fit 2 into 5 , without splitting the number, which gives us 2, the quotient. After this, we still have 1 leftover, which is our remainder.

This is particularly useful for returning the time taken for a process to run — in hours, minutes, and seconds. Like so:

[Out]: "08:00:08"

*args, **kwargs

Occasionally, you may notice that a function definition contains these two arguments, like def func(x, y, *args, **kwargs).

They’re both incredibly simple features and allow us to pass multiple values to a function, which will then be packed into a generator.

It has a similar outcome as if we passed a list/generator to a standard argument:

def func(values):
    for x in values:
        print(x, end=" ")func([1, 2, 3])

[Out]: '1 2 3 '

Now, let’s use *args — this will allow us to pass each value as a new argument, rather than containing them all within a list.

def func(*values):
    for x in values:
        print(x, end=" ")func(1, 2, 3)

[Out]: 1 2 3

Note that we didn’t need to type *args. Instead, we typed *values. The variable name we use is irrelevant. It is defined as an *args, thanks to the single asterisk *.

*args simply creates a tuple from the arguments we pass into a function.

**kwargs on the other hand, creates a dictionary. Hence the name, key-word arguments. We use it like so:

def func(**values):
    for x in values:
        print(f"{x}: {values[x]}")func(x=1, y=2, z=3)[Out]: x: 1
       y: 2
       z: 3

Again, we can call the variable whatever we want. In this case, we used **values. It is defined as a **kwargs by the use of a double asterisk **.

Comprehensions

This is definitely one of the most useful features of Python. Comprehension expressions are unmissable. The most common is the list comprehension. I’m sure the vast majority of you will have seen these:

vals = [1, 2, 3, 4, 5][i**2 for i in vals]

[Out]: [1, 4, 9, 16, 25]

But we are not limited to those square brackets. We can define a generator expression with almost the exact same syntax:

(i**2 for i in vals)

[Out]: <generator object <genexpr> at 0x7f0281730fc0>

Of course, each element in the generator will only be output when called, which we can do with list():

list((i**2 for i in vals))

[Out]: [1, 4, 9, 16, 25]

With another small change of syntax, we can even build dictionaries using dictionary comprehensions:

{i: i**2 for i in vals}[Out]: {1: 1,
        2: 4,
        3: 9,
        4: 16,
        5: 25}

casefold

This string method is particularly interesting. It functions in a similar way to lower. However, casefold attempts to standardize, more aggressively, a wider range of characters.

In most cases, lower and casefold behave the same, but occasionally, they do not:

"ς".casefold()  # both ς and σ are the Greek letter sigma[Out]: "σ"

In comparison, using lower:

"ς".lower()  # however, lower recognizes them as different[Out]: "ς"

[Out]: False

Here, both sigmas are already lower-case. Depending on the use-case, it may function as expected.

However, if we intended to compare two equivalent Greek words, one using σ and the other ς, only casefold would allow us to compare them accurately:

I hope you have gained something from this article. In particular, divmod and casefold are both very interesting features that I personally had never used until very recently.

This article was originally published on Towards Data Science by James Briggs, an AI Consultant based in London. He is fascinated by the phenomenal advances that are being made within the tech eco-system daily and loves writing about AI, Python, and programming in general. Follow him on Twitter.

Read next: How to protect AI systems against image-scaling attacks