Blog post

Handy Python Tips

ยท 6 min read

Python is a flexible programming language that is well-known for its simplicity and numerous features that make programming in it a lot faster. This article presents just a few that might speed up your productivity a little bit.

1. Tuple expansion

a, b = tuple([1, 2])
s1, s2 = input(), int(input())

Tuple expansion is one of Python's most powerful features, allowing you to assign multiple values or expand multiple values of a tuple in a single line.

>>> print(a, b)
1 2
>>> print(s1, s2)
baguette
pomme
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: invalid literal for int() with base 10: 'pomme'

The code above effectively assigns a tuple (a, b) to another tuple (1, 2), and is equivalent to the code below:

a = 1
b = 2
s1 = input()
s2 = int(input())

This can let you return multiple values from a function.

def init():
    return (5, 6)

a, b = init()
print(a, b)

Output:

5 6

Tuple expansion is also used in for loops to iterate over tuples or even dictionaries.

array = [
    (1, 2),
    (3, 4),
    (5, 6)
]

items = {
    7: 8,
    9: 10,
    11: 12
}

for i, j in array:
    print(i, j)

for k, v in items.items():
    print(k, v)

Output:

1 2
3 4
5 6
7 8
9 10
11 12

2. Nicer iteration with zip() and enumerate()

Python's for loop is commonly known in other programming languages as a for-each loop. This is great if you just want each item in an iterable, but sometimes you want the index too! Instead of having to resort to range(len(array)), instead you can use enumerate() and tuple expansion to easily get both the index of the element and the element itself:

array = ["a", "b", "c", "d", "e"]
for i, c in enumerate(array):
    print(i, c)

Output:

0 a
1 b
2 c
3 d
4 e

In a similar vein, if you have two arrays you want to process at the same time, you don't need to use range(len(array)) when you have zip(), which will bundle the different iterators into one big one as big as the smallest iterable.

ints = [1, 2, 3, 4]
strs = ("pomme", "poutine", "pinterest", "pear")
floats = [1.0, 2.0, 3.0, 4.0, 5.0, 6.0]
for i, s, f in zip(ints, strs, floats):
    print(i, s, f)

Output:

1 pomme 1.0
2 poutine 2.0
3 pinterest 3.0
4 pear 4.0

3. Iterable unpacking

In competitive programming, often you have to print out space-separated results. This can be done by the mildly inconveniencing

print(" ".join([1, 2, 3, 4]))

or heaven forbid, via iteration:

for i in [1, 2, 3, 4]:
    print(i, end=" ")
print()

which is where iterable unpacking comes in, and you can go straight to

print(*[1, 2, 3, 4])

The unpacking operator (the asterisk) basically gets rid of the container and throws all of the elements inside directly into the print function as parameters.

That means that the above line of code is equivalent to:

print(1, 2, 3, 4)

which nicely prints out the integers separated by spaces with a newline at the end.

But wait, there's more! The unpacking operator is also commonly used in function definitions as a catch-all parameter for extra arguments, stuffing them into a list.

def init(a, b, *args):
    print(a, b)
    print(args)

init(1, 2, "pomme", 4, 6.0)

Output:

1, 2
['pomme', 4, 6.0]

You can also use this in normal assignment:

a, *args, b = (1, 2, 3, 4, 5)
print(a)
print(args)
print(b)

Output:

1
[2, 3, 4]
5

And it can be used as a handy way to expand a list instead of using list(). The comma at the end of the variable is there to indicate it is a tuple with a single element (a singleton).

*s, = "abcde"
print(s)

Output:

['a', 'b', 'c', 'd', 'e']

4. map()

This makes one-liners super easy in Python. map() takes a function in the first parameter and applies it to all values in the iterable in the second parameter.

def readints(string):
    print(list(map(int, string.split()))
readInts("1 2 3 4 5")

Output:

[1, 2, 3, 4, 5]

It's most useful in assigning variables easily when you know the format the input will be in.

a, b = (map(int, input().split()))

5. List generators

You can generate a new list using inline for.

array = [i for i in range(10)]
print(array)

Output:

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

6. One-line prefix sum array

A prefix sum array is a common data structure used in competitive programming. Python's itertools module has a wide array of functionality that can make this easier. A traditional PSA requires three lines:

psa = [0]
for i in [1, 2, 3]:
    psa.append(psa[-1] + i)

Excluding the import, you can shrink it down to one with itertools:

import itertools
*psa, = itertools.accumulate([1, 2, 3])

Licensed under the AGPL-3.0 on GitHub and Gitea