Writing Idiomatic Python Code
Tags: python, discuss, beginners
Published: 2022-06-06 14:14:18


You need to understand Python well before you can write idiomatic, or *pythonic* code in it.

But what does that even mean?

Here are some examples



## Falsy and Truthy

Almost all data types can be interpreted as bool-ish. An empty list? Fals-y. A 3-character string? Tru-thy


```python
# Instead of writing something like this
a = [1, 2, 3]
if len(a) > 0:
    ...

# You could write:
a = [1, 2, 3]
if a:
    ...
```


## Ternary operator

Python does have a ternary operator by leveraging one-line 𝚒𝚏s:

```python
# Instead of the lenghty version
a = True
value = 0
if a:
  value = 1

# You could shorten it to:
a = True
value = 1 if a else 0
```


## Chained Comparison Operators

Python syntax should be as simple as possible. That's why you can use mathematics-like notations like this

`𝟻 < 𝚡 < 𝟷𝟶`


```python
# Instead of this
if x < 10 and x > 5:
  ...

# you can write this
if 5 < x < 10:
  ...
```




## Multiple assignment and destructuring assignment

You can assign different variables in one line of Python code

```python
# Instead of writing
x = 'foo'
y = 'foo'
z = 'foo'
# or
a = [1, 2, 3]
x = a[0]
y = a[1]
z = a[2]

# you could simplify to:
x = y = z = 'foo'
# and
a = [1, 2, 3]
x, y, z = a
```


## f-strings

f-strings provide a template-like mini-language inside Python. You can, for example, align text, or specify precisions of `float`s.

```python
username = "Bas"
monthly_price = 9.99

# Instead of transforming each element,
print(username.rjust(10), '|', "{:3.2f}".format(monthly_price))

# you can use a single f-string
print(f"{username : >10} | {monthly_price:3.2f}")

```



## list comprehensions / dict comprehensions

list and dict comprehensions are maybe the most Pythonic feature. It can be very useful for modifying data structures.

```python
usernames = ["alice", "bas", "carol"]

# Instead of a loop:
users_with_a = []
for username in usernames:
    if username.startswith("a"):
        users_with_a.append(username)
# Use a list comprehension
users_with_a = [username for username in usernames if username.startswith("a")]

# Same for dicts: Instead of a loop
users_dict = {}
for username in usernames:
    users_dict[username] = get_user_id(username)
# you can use dict comprehensions
users_dict = {username: get_user_id(username) for username in usernames}

```
----

## `in` keyword

Python has the `in` operator that works on collections, like lists.

You could use it to check if an element is in a list of choices

```python
name = 'Alice'
found = False
if name == 'Alice' or name == 'Bas' or name == 'Carol':
  ...

name = 'Alice'
if city in {'Alice', 'Bas', 'Carol'}:
    ...
```

## `enumerate`

Whenever you need to not only access each element by a list but also need a counter in your loop, you can use `enumerate`

```python
a = ["A", "B", "C"]

# Instead of using an index variable
for i in range(len(a)):
    print(i, a[i])

# you could iterate the list as usual and attach a counter
for counter, letter in enumerate(a):
    print(counter, letter)
```


## The Walrus Operator

With the walrus operator introduced in Python 3.8, you have an assignment expression.
That means that you could assign a value to a variable and access that value in the same line.

```python
n = len(a)
if n > 10:
    print(f"List is too long ({n} elements, expected <= 10)")

if (n := len(a)) > 10:
    print(f"List is too long ({n} elements, expected <= 10)")
```


## `assert`

Assertions inside your code not only make it safer but also help with understanding your rationale behind a particular line.


```python
# Instead of a comment
def activate_user(user):
    # User has to be a `UserModel` object
    user.active = True
    user.save()

# you can use assert
def activate_user(user):
    assert type(user, UserModel)
    user.active = True
    user.save()
```

## Pattern Matching

Pattern Matching is a very handy feature added in Python 3.10.

I had a Twitter thread on this in March:

{% embed https://twitter.com/bascodes/status/1499012013380489217 %}

What are some things you consider as idiomatic Python? 

Share your ideas! 💡👋