Two Faced Python

Nishant Joshi
6 min readNov 13, 2022

Python, what an interesting thing, we could find it in rainforests, grassland, swamps, woodland, rocky outcrops, desert sand hills, or scrublands but more importantly in enterprise-level servers and backend developers’ dens.

But as much as we all love this language there are so many things we don’t know about it, a language known for simplicity and ease of use; has features so confusing or hilarious that you might start to doubt yourself about the way to you code in python and if you could make it any better?

credits: god tier meme maker who I don’t know

So, without wasting any of your time, let’s look at some awesome facts about python

Disclamer: there are snippets of code that could cause you some serious existential crisis. (code alert!)

Weird Imports 👻

  1. Try this in your python .py file or interpreter
import this

this imports, what is important for every python programmer, just check it out!
Also known as the “zen of python”

But if you are lazy, to try it out this is what happens when you run it

Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!

I am not gonna explain it, or even try to make sense of it. This is what the developer wrote.

2. Try out antigravity for a change

import antigravity

I highly recommend you check it out. I don’t want to add some more credits to a python developer's laziness.

3. The future is very bright

from __future__ import braces

This just shows how savage python is. After running this command python will throw a Syntax Error, something like:

SyntaxError: not a chance

Now, I wonder what that is. Maybe there are languages out there that have tainted braces (looking at you java 👀)

Mystery Features 🔮

Enough with these useless facts let’s learn about some useful yet, very rarely used features of python

For;else;where

What does that mean? everyone has heard of if ... else ... statements, have you heard of where ... else ... or for ... else ... statements?

Ya! They exist, and I assure you they are genuine. Let’s look at an example:

let’s say you input any number between 0–99, the output will be

You broke it!😡
It ends here!

Otherwise, the output will be

It just doesn't break. 😇
It ends here!

This else statement in both for and while loops was introduced to check if the loop ended naturally or was interrupted with a break statement.

walrus

credits: https://biologydictionary.net/

Yup, this animal is also present in python. Though it looks much more innocent. := that’s the walrus operator.

Let’s look at an example

it’s a form of assignment expression which also spits out a value, experiment with it, it’s quite useful.

The only downfall is that it is introduced in 3.8+ python versions

lazy is fast

Processing a stream of data, want to create an array of data and use it in order; why waste time using list comprehension, we have the next best thing! generators

What are generators? we are all familiar with the range function:

for i in range(1, 10000000):
print(i)

When we run this code, it starts executing the for loop directly but shouldn’t it first list all the numbers from 1 to 9999999 and then go over it?

If that was the case:

for i in list(range(1, 10000000)):
print(i)

This code will be very slow and inefficient, on top of that it will use a lot of memory.

Hence, the range function is a form of a generator, hooked yet? wanna know more about generators? I got you!

There are 2 main ways to create generators first using yield and second using parenthesis. Let’s check out the parenthesis way of doing things

Just look at that difference one takes about 0.4s while the other takes about 2.7s. This is a phenomenal difference, by just changing the type of brackets we use. This is because of the lazy loading feature of the generator, the only point where computation actually happens is while iterating over the output, which we are doing here on line 15 and we can cascade generators with each other generators to create a cascaded lazy loading gizmo. This makes the code extremely fast, but we don’t have the computed output at the very end to actually get the output we have to convert it to a list or iterate over it, at that point the execution starts to happen from the very first iterator to the very last.

Now, let’s look at the other way of creating a generator, i.e. through yield keyword, let’s look at an example:

This is a very simple example of using a generator to go over a file, as the file size increases the superpower of generators starts to become apparent. There is no overhead when it comes to memory, the processing is only done when needed and soo much more…

There is much more cool stuff you can do with generators, and a lot of information is available on various online forums.

Do you think that’s it? No there is one more cool trick that you can do with the yield keyword. Message Passing.

Yup, you heard me right we can pass messages inside a generator while it is generating new data.

Let’s look at an example:

Code example for yield with send

Just read through the code once, a few different things are going on here. Focus mostly on lines 16, 22, and below. What does the expression
... = yield ... do?
It turns out, it actually tries to get a value from outside into the generator, and for that to work instead of calling next every time we need .send a value to actually pass a value inside. Otherwise, the value is always None .

The question is why did I call next the first time around? Turns out you cannot pass a value to a newly created generator by calling the next() on the generator, I have now effectively reached to statement yield message , which is ready to take input, which I then pass in on line 22.

After all said and done, the python community keeps adding new features in their every release, I don’t think I would be able to include them all in a single blogpost, but maybe I could create another one of these articles explaining some new and exciting features of python or maybe rust!

Tell me and I forget, teach me and I may remember, involve me and I learn.” — Benjamin Franklin

--

--

Nishant Joshi

Developer, Programmer, learner, and curious human being