{ }codelper

Learn › Python

Language-specific · 40

Pythonic code

Comprehensions, slicing with steps, unpacking, enumerate and zip, in, f-strings, and three traps.

This lesson is for Python.
Other languages do the same work with loops or library methods (JavaScript map/filter, Java streams, C# LINQ, and loops with push_back/Add in C, C++ and Craykon).

Python has many short forms that turn several lines of loop into one.
The example below tries comprehensions, slicing, unpacking, enumerate, zip and f-strings in turn, and ends with two traps that give a wrong answer without any error.

nums = list(map(int, input().split()))words = input().split() odd_squares = [x * x for x in nums if x % 2 == 1]print(*odd_squares)print({x % 3 for x in nums})print({w: len(w) for w in words}) print(*nums[::-1])print(*nums[1:6:2])print(words[0][::-1]) first, *rest = numsa, b = first, rest[-1]a, b = b, aprint(a, b, len(rest)) for i, w in enumerate(words, start=1):    print(f"{i}. {w:<6}|")print(*(f"{w}={n}" for w, n in zip(words, nums)))print(9 in nums, "lo" in words[0]) gen = (x for x in nums)print(sum(gen), sum(gen)) grid = [[0] * 3] * 2grid[0][0] = 1print(grid)grid = [[0] * 3 for _ in range(2)]grid[0][0] = 1print(grid)
stdin
3 1 4 1 5 9 2 6
hello world codes
stdout
9 1 1 25 81
{0, 1, 2}
{'hello': 5, 'world': 5, 'codes': 5}
6 2 9 5 1 4 1 3
1 1 9
olleh
6 3 7
1. hello |
2. world |
3. codes |
hello=3 world=1 codes=4
True True
31 0
[[1, 0, 0], [1, 0, 0]]
[[1, 0, 0], [0, 0, 0]]

Key points

  • A comprehension builds a new list from a loop in one line.
    [x * x for x in nums if x % 2 == 1] reads "the squares of the odd numbers in nums", and it replaces a four-line loop that calls append on an empty list.
  • Change the brackets and the same shape makes a set, {x % 3 for x in nums}, or a dict, {w: len(w) for w in words}.
  • Slicing a[start:stop:step] excludes the stop, and missing parts default to the beginning, the end and 1.
    nums[1:6:2] takes indexes 1, 3 and 5, nums[::-1] is a new reversed list, and "hello"[::-1] is "olleh".
  • A slice past the end is not an error; it just gives what is there (nums[5:100]).
    Negative indexes count from the back, so a[-1] is the last item.
  • Unpacking: a, b = b, a swaps without a temporary variable, and first, *rest = nums splits off the first value and a list of the rest.
    For an index use enumerate(words, start=1); to walk two lists side by side use zip(words, nums) (it stops at the shorter one).
  • in asks whether something is there.
    A list is searched one item at a time, which is slow, while a set or dict finds it almost at once.
    On strings, "lo" in "hello" looks for a substring.

How each language writes it

PythonAn f-string f"{i}. {w:<6}|" puts expressions in braces and the format after : (<6 left-aligned in 6 columns, .2f two decimal places).
f"{x=}" prints the name too, as x=3, which helps when debugging.
Looping over range(len(...)) is rare, and slicing with a step or [::-1] is a short form only Python has

Common mistakes

[] as a default value

def add(x, bucket=[]):
    bucket.append(x)
    return bucket
add(1); print(add(2))

→ [1, 2] — the [] is created only once, when the function is defined, so every call shares the same list

Use bucket=None and make a new list inside with if bucket is None: bucket = [].

Using a generator twice

gen = (x for x in nums)
print(sum(gen), sum(gen))

→ 31 0 — parentheses ( ) make a generator, not a list, and it is empty after one use

If you need it twice, make a list with square brackets [ ].

Making a 2D list with [[0] * 3] * 2

grid = [[0] * 3] * 2
grid[0][0] = 1
print(grid)

→ [[1, 0, 0], [1, 0, 0]] — the outer * 2 does not copy the inner list; it holds the same list twice

Make each row new with a comprehension, [[0] * 3 for _ in range(2)] (multiplying numbers, as in [0] * 3, is fine).

How languages differ
A 2D list made with * m and a =[] default both share one list without any error, so changes show up in the wrong place.
Use a comprehension when you want several lists, and None as the default.

Practice