CoreMesh

Python One Liners: Runnable Examples for Everyday Tasks

Useful Python one-liners grouped by task: one-line if/else, one-line for loops, itertools and script helpers, each one runnable, plus when not to use them.

Python One Liners: Runnable Examples for Everyday Tasks

A Python one-liner is a complete, useful piece of work written as a single line: a conditional expression, a comprehension, a sorted() call with the right key, or a couple of itertools functions chained together. The ones worth knowing are the ones you'd actually type into a script, not the ones that win code golf.

Below are one-liners grouped by task. The one-line if, the one-line for loop, and list and dict tricks come first, then helpers for small scripts. The last two sections cover when a one-liner is the wrong choice and the mistakes that catch people, because "fits on one line" and "is a good idea" aren't the same thing.

What a Python one-liner is and when it fits#

Python has no special one-liner mode. A one-liner is just an expression that produces a value, so it can sit on the right side of an assignment, inside a function call, or after return. Three language features do almost all of the work:

  • Conditional expressions: a if condition else b.
  • Comprehensions: [f(x) for x in items if keep(x)], with dict and set forms too.
  • Generator expressions fed to a built-in such as sum(), any(), max(), or next().

The standard library leans on the same idea. The itertools recipes in the official docs have a section literally called "Basic one liners", with helpers such as take, flatten, nth, quantify, and first_true. Several of the entries below are those recipes with the function wrapper removed.

My rule of thumb: a one-liner fits when you can read it aloud as one sentence. "Grades are pass if the score is at least 60, else fail, for each score" is a one-liner. If you need a breath in the middle, write the loop.

Python one line if and if else#

The one-line if else is a conditional expression. It evaluates to a value, so it goes anywhere a value goes:

python
status = "ok" if code == 200 else "error"
print("even" if n % 2 == 0 else "odd")

A plain one-line if statement with no else is also legal. Python lets a single simple statement follow the colon:

python
if debug: print("request", url)

That's fine for a guard or a debug print. Once the body grows past one call, move it to its own indented block.

For three branches, conditional expressions chain from left to right:

python
label = "negative" if n < 0 else "zero" if n == 0 else "positive"

There's no elif in expression form. Two levels read fine. Beyond that, an if/elif/else block is clearer and easier to step through in a debugger. The full grammar is in the conditional expressions reference.

python
scores = [88, 42, 95, 60, 73]
grades = ["pass" if s >= 60 else "fail" for s in scores]
print(grades)

n = -3
print("negative" if n < 0 else "zero" if n == 0 else "positive")

verbose = True
if verbose: print("a one-line if statement, no else needed")

Python one line for loop with comprehensions#

The one-line for loop in Python is a comprehension. It builds a new collection from an iterable, optionally filtering as it goes:

python
squares = [n * n for n in range(10)]
evens = [n for n in range(20) if n % 2 == 0]
lengths = {w: len(w) for w in words}
initials = {w[0] for w in words}

Nested loops collapse into one comprehension with the for clauses in the same order you'd write them as blocks, outer loop first:

python
flat = [x for row in matrix for x in row]

When you only need an aggregate, drop the brackets and pass a generator expression straight to the built-in. sum(n * n for n in range(1_000_000)) never builds the million-item list; it feeds values to sum() one at a time. The same works with any(), all(), max(), min(), and ", ".join().

One distinction matters here. A comprehension is for building a result. If the goal is a side effect, such as printing each item, write the plain statement for x in items: print(x) on one line. Don't write [print(x) for x in items]. It works, but it allocates a list of None values just to throw it away, and anyone reading it will stop to wonder what the list was for.

python
words = "the quick brown fox jumps over the lazy dog".split()
print({w: len(w) for w in words})

matrix = [[1, 2, 3], [4, 5, 6]]
print([x for row in matrix for x in row])
print(list(zip(*matrix)))

print(sum(len(w) for w in words))
print(any(len(w) > 4 for w in words), all(w.islower() for w in words))

One-liners for lists, dicts and iterators#

These cover the everyday data-shaping jobs. The itertools ones need from itertools import ... at the top of the file. Counter comes from collections and itemgetter from operator.

Task One-liner Note
Flatten one level list(chain.from_iterable(nested)) The flatten recipe
First n items of any iterable list(islice(it, n)) The take recipe
Nth item or a default next(islice(it, n, None), default) The nth recipe
First item matching a test next(filter(pred, items), default) The first_true recipe
Count items passing a test sum(map(pred, items)) The quantify recipe
Dedupe, keep first-seen order list(dict.fromkeys(items)) Items must be hashable
Split into chunks of n list(batched(items, n)) Last chunk may be short
Adjacent pairs list(pairwise(items)) (a, b), (b, c), ...
Running total list(accumulate(items)) Pass max or operator.mul for other folds
Transpose rows and columns list(zip(*rows)) Truncates to the shortest row
Sort a dict by value sorted(d.items(), key=itemgetter(1), reverse=True) Returns a list of pairs
Top k most common Counter(items).most_common(k) Works on any iterable of hashables
Merge two dicts {**a, **b} Later keys win
Invert a dict {v: k for k, v in d.items()} Values must be hashable and unique
python
from itertools import accumulate, chain, islice, pairwise
from collections import Counter
from operator import itemgetter

nested = [[1, 2], [3], [4, 5, 6]]
print(list(chain.from_iterable(nested)))
print(list(pairwise([10, 13, 17, 30])))
print(list(accumulate([3, 4, 6, 2, 1, 9], max)))
print(list(islice((n for n in range(100) if n % 7 == 0), 5)))
print(list(dict.fromkeys("mississippi")))

hits = {"home": 12, "about": 3, "blog": 40}
print(sorted(hits.items(), key=itemgetter(1), reverse=True))
print(Counter("mississippi").most_common(2))
print(next(filter(lambda n: n > 20, [4, 9, 25, 31]), None))

If you want more of these, the recipes page notes that substantially all of them, plus many others, ship in the more-itertools package, installed with python -m pip install more-itertools.

One-liners for small automation scripts#

Most throwaway scripts do the same handful of jobs: count things, group things, sort things, and print the result. Each of those is one line.

Word frequency from a block of text:

python
top = Counter(text.casefold().split()).most_common(10)

Group records by a key. This is the one people get wrong most often, so note the sorted() call. groupby() only groups consecutive runs, so unsorted input gives you one group per run, not one group per key:

python
by_team = {k: list(g) for k, g in groupby(sorted(rows, key=itemgetter("team")), key=itemgetter("team"))}

That line is right at the limit of what I'd keep on one line. Pulling key = itemgetter("team") out into its own assignment first makes it much easier to read.

Pad uneven inputs so a loop sees every value from both sides instead of stopping at the shorter one:

python
pairs = list(zip_longest(names, emails, fillvalue=""))

Case-insensitive sort using str.casefold, the same key the unique_justseen recipe uses:

python
ordered = sorted(names, key=str.casefold)

Print a dict readably while debugging. json.dumps(data, indent=2) lays nested structures out over multiple lines.

Pull tokens out of a string is a regex job, and re.findall() returns every match as a list in one call. The patterns themselves are the bigger topic.

Once a script needs to keep results between runs, a one-liner stops being the right tool. A small sqlite3 script is the usual next step.

When not to write a one-liner#

A one-liner is a readability choice, not a performance one. Short code isn't automatically faster code. The itertools documentation says high speed is retained by preferring "vectorized" building blocks over for-loops and generators, which incur interpreter overhead. Here's when I'd expand a line back out:

  • The expression has side effects. Comprehensions that call functions for their effects, like writing files or sending requests, hide the loop that matters most.
  • You'd need to debug it. You can't set a breakpoint halfway through an expression, and you can't name an intermediate value to inspect it. A three-line version with named steps costs nothing at runtime.
  • There are two or more conditional expressions. Nested a if x else b if y else c reads fine on its own. Stacked inside a comprehension, it doesn't.
  • A lambda is being assigned to a name. square = lambda n: n * n is a def with a worse traceback. Use lambda inline as a key or predicate, and def for anything you give a name.
  • Someone else will maintain it. Reviewers read loops faster than they unpack map(map, repeat(is_not), ...). The derangements recipe in the docs is a fine piece of iterator algebra and also a good example of code most teams shouldn't write for themselves.

Chaining itertools functions does have a benefit beyond brevity. The docs point out these tools process elements one at a time rather than bringing the whole iterable into memory. That's a reason to prefer islice and chain over slicing and list concatenation when the input is large or infinite. It's not a reason to squash everything else onto one line.

Common mistakes and gotchas#

  1. Grouping without sorting. groupby() groups adjacent items only. Sort by the same key first, or use Counter or a dict of lists.
  2. Building a grid with *. [[0] * 3] * 3 makes three references to the same inner list, so changing one row changes all three. Write [[0] * 3 for _ in range(3)] instead.
  3. Silent truncation in zip(). zip() stops at the shortest input. The grouper recipe shows both fixes: pass strict=True to raise an error on mismatched lengths, or use zip_longest() with a fillvalue to pad.
  4. Consuming an iterator twice. Generators, map(), filter(), and every itertools function return single-pass iterators. A second loop over the same object sees nothing. Call list() once, or use tee() to split it.
  5. The and/or trick. cond and a or b is an old idiom from before conditional expressions existed. It returns b whenever a is falsy, such as 0, "", or []. Use a if cond else b.
  6. Deduping with set() when order matters. list(set(items)) drops the original order. list(dict.fromkeys(items)) keeps the first occurrence of each item.
  7. Calling list() on an infinite iterator. count(), cycle(), and repeat() without a count never end. Truncate with islice() or takewhile() before collecting.
  8. Unparenthesized conditional expressions inside bigger expressions. x + 1 if flag else 0 means (x + 1) if flag else 0, not x + (1 if flag else 0). Add parentheses whenever anything else shares the line.

Quick reference#

Copy what you need:

  • One-line if else: a if cond else b
  • One-line if statement: if cond: do_something()
  • Three branches: a if x else b if y else c (stop at two levels)
  • List, dict, set comprehensions: [f(x) for x in it if keep(x)], {k: v for ...}, {x for ...}
  • Aggregate without a list: sum(f(x) for x in it), any(...), max(...)
  • First match or default: next(filter(pred, it), None)
  • Flatten: list(chain.from_iterable(nested))
  • Chunk: list(batched(it, n))
  • Dedupe in order: list(dict.fromkeys(it))
  • Sort by value: sorted(d.items(), key=itemgetter(1))
  • Most common: Counter(it).most_common(k)

Before committing a one-liner, check three things: it reads as one sentence, it has no side effects, and nobody will need a breakpoint in the middle of it. If any of those fails, the loop was the right answer.

Quick answers

What is a Python one-liner?

A single line of Python that does a complete job, usually a conditional expression, a comprehension, or a generator expression passed to a built-in like sum() or next(). It's a style choice, not a language feature, and brevity alone doesn't make it faster.

How do you write an if else on one line in Python?

Use a conditional expression: value = a if condition else b. For a bare if with no else, a single simple statement can follow the colon, as in if debug: print(x).

How do you write a for loop on one line in Python?

Use a comprehension, such as [n * n for n in range(10)], or a generator expression inside a built-in, such as sum(n * n for n in range(10)). For a loop that only has side effects, write for x in items: print(x) rather than a comprehension.

Is there a Python one-liners book or PDF?

Christian Mayer wrote a book titled Python One-Liners, published by No Starch Press. For a free official reference, the itertools recipes page in the Python docs has a section called Basic one liners, and the same recipes are available in the more-itertools package on PyPI.

What is Python, in one line?

Python is a general-purpose, high-level programming language with a large standard library, used for scripting, automation, web backends, and data work.

Did this solve it?

One tap. No account.

Saved you an hour? Send a tip.

USDC or ETH on Base, Ethereum, Arbitrum and more. Keeps the notes free and the examples running.

Base

Network

0xc783bc5c3fa14cEC3f09A22284bC91C5AF0d59e1
Open in wallet · 5 USDC

On a computer? Scan the code with your phone wallet, or copy the address.

Pick the network your wallet or exchange uses. USDC works on all six; ETH on Base, Ethereum, Arbitrum and Optimism. Don't send on Tron or Solana: this address doesn't exist there. Tips are optional and unlock nothing; every guide stays free.

Discussion

Start the discussion

Indra Wijaya

Builds and runs AI agents, bots and content pipelines, and writes down what works and what broke.

About · Email · RSS

Keep reading

New notes, no spam.

One post at a time, only when there's something worth reading. Follow in any feed reader.

Subscribe via RSS