I learned a few pythonic tricks and shortcuts I want to share with you while solving a programming puzzle called Alien Dictionary (leetcode πŸ”’, tutorial cup).

Else after a for loop

In Python, else can be used with for and while loops. The code within the else block executes once the loop has finished iterating over all items. If the loop is exited prematurely with a break statement, then the else block is not executed.

ans = ''
chars = ['h', 'i', ' ', 'm', 'o', 'm']
for c in chars:
    ans += c
else:
    ans += '!'
print(ans)
# hi mom!

Zip protects you from out of bounds indexes

If you want to iterate through an interable and compare elements to the ones next to themselves, use zip() on the iterable, and on the same interable indexed from 1.

zip() stops creating tuple pairs once one of the iterables is exhausted.

nums = list(range(10))
sorted = True
for a, b in zip(nums, nums[1:]):
    if a > b:
        sorted = False
        break
print(sorted)

If instead you want the tuples to include all elements from both iterables, replace zip() with itertools.zip_longest(). For the missing values from the shorter interable you can supply a fillvalue argument such as None.

Dictionaries with a default value

Ordinary python dicts throw an exception if you try to index a key that doesn’t exist.

d = {}
d['a']
# KeyError: 'a'

If you want a default value for missing keys, use collections.defaultdict.

from collections import defaultdict
d = defaultdict(int)
d['a']
# 0

The argument to defaultdict is a function that returns the default value when called. In this case, int() returns 0. Another possibility is set() to create an empty set.

To hardcode a value, write a short lambda function that returns it.

from collections import defaultdict
d = defaultdict(lambda: 42)
d['a']
# 42

Nested list comprehensions

These are controversial since some think they are hard to read, but are very powerful.

import pprint
words = ['physics', 'chemistry', 'biology']
degrees = {c : 0 for word in words for c in word}
pprint.pprint(degrees)
{'b': 0,
 'c': 0,
 'e': 0,
 'g': 0,
 'h': 0,
 'i': 0,
 'l': 0,
 'm': 0,
 'o': 0,
 'p': 0,
 'r': 0,
 's': 0,
 't': 0,
 'y': 0}

This code sets up part of a graph data structure succintly. To get some intuition for nested list comprehensions, read this Stack Overflow answer.