DEV Community

samconibear
samconibear

Posted on • Edited on

Pythonic Peculiarities

I recently had what I described to some friends as a 'revelation'. Thinking I'd had some kind of spiritual awakening or deep philosophical discovery they were slightly underwhelmed when I told them Id developed a deeper level of understanding of another one of Python's unique quirks.

In this post I wanted to address some of the features of the language that make it so unique compared to other programming languages.


Exceptions as Part of Logic

While in any other language throwing an error is a resource intensive procedure and as such should never be used to control the flow of a program. This is not true with python, as throwing is both less costly, and the sluggishness of the language in general means alternatives flow control methods are no quicker.

There are many in the python community that advocate for using exceptions as part of control logic, and there are some scenarios where it could improve readability. For example, consider the scenario of obtaining an item nested deep within a dictionary, where a key/value may or may not exist at any level of the nested structure:

d = {"a": {"b": {"c": {"d": {"e": "exists"}}}}}
Enter fullscreen mode Exit fullscreen mode

Traditional Style:

if "a" in d \
   and "b" in d["a"] \
   and "c" in d["a"]["b"] \
   and "d" in d["a"]["b"]["c"] \
   and "d" in d["a"]["b"]["c"] \
   and "e" in d["a"]["b"]["c"]["d"]:
      return d["a"]["b"]["c"]["d"]["e"]
else:
   return "does not exist"
Enter fullscreen mode Exit fullscreen mode

Using the Exception style reduces the code to:

try: 
   return d["a"]["b"]["c"]["d"]["e"]
except (KeyError):
   return "does not exist"
Enter fullscreen mode Exit fullscreen mode

Complex Index Slicing

Python makes slicing very syntactically simple through the use of negative slice parameters allowing you to index counting from the end of the array, and when provided as a step, re-index from the back of the array:

a[-1]       # get the last element
a[-5:-1]    # get the last 5 elements
a[-5:-1:-1] # same as above, but reversed
a[::-1]     # Cheeky one liner to reverse a string / list.
Enter fullscreen mode Exit fullscreen mode

It's clear that this feature is must appriciated by developers, as javascript implemented the .at() method in ECMAScript 2022, allowing devs to finaly mimic this functionality.


List, Set & Generator Comprehensions

This wouldn't be a python feature list without including the famous list comprehension. Without going into too much detail, comprehensions can be used to re-write common iterative behaviors in one liners.

Comprehension can be used in place of the map function, for example:

# Find the transpose of a matrix
m = [[1,2,3], [4,5,6], [7,8,9]]
transpose = [[r[i] for r in m] for i in range(3)]

# Find primes under 100
{x for x in range(2, 100) if all(x % y for y in range(2, x))}

# Update an existing dictionary
d = {'a': 1, 'b': 2, 'c': 3}
{ k: v+1 for (k, v) in d.items() }

# Square number generator
(i * i for i in range(100))
Enter fullscreen mode Exit fullscreen mode

Using Indentation for Scope

I've added this as a bit of a joke, however I think most python devs would agree that using indentation to define scope slows development and makes the language feel clunky. It's not all sunshine and rainbows...
Image description


I have had this post sitting in my drafts for ages, but I am tempted to make this into a series, as there are still some other python features I'd like to discuss.

Top comments (0)