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.

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(), ornext().
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:
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:
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:
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.
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:
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:
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.
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 |
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:
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:
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:
pairs = list(zip_longest(names, emails, fillvalue=""))
Case-insensitive sort using str.casefold, the same key the unique_justseen recipe uses:
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 creads fine on its own. Stacked inside a comprehension, it doesn't. - A
lambdais being assigned to a name.square = lambda n: n * nis adefwith a worse traceback. Uselambdainline as a key or predicate, anddeffor anything you give a name. - Someone else will maintain it. Reviewers read loops faster than they unpack
map(map, repeat(is_not), ...). Thederangementsrecipe 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#
- Grouping without sorting.
groupby()groups adjacent items only. Sort by the same key first, or useCounteror a dict of lists. - Building a grid with
*.[[0] * 3] * 3makes three references to the same inner list, so changing one row changes all three. Write[[0] * 3 for _ in range(3)]instead. - Silent truncation in
zip().zip()stops at the shortest input. Thegrouperrecipe shows both fixes: passstrict=Trueto raise an error on mismatched lengths, or usezip_longest()with afillvalueto pad. - Consuming an iterator twice. Generators,
map(),filter(), and everyitertoolsfunction return single-pass iterators. A second loop over the same object sees nothing. Calllist()once, or usetee()to split it. - The
and/ortrick.cond and a or bis an old idiom from before conditional expressions existed. It returnsbwheneverais falsy, such as0,"", or[]. Usea if cond else b. - Deduping with
set()when order matters.list(set(items))drops the original order.list(dict.fromkeys(items))keeps the first occurrence of each item. - Calling
list()on an infinite iterator.count(),cycle(), andrepeat()without a count never end. Truncate withislice()ortakewhile()before collecting. - Unparenthesized conditional expressions inside bigger expressions.
x + 1 if flag else 0means(x + 1) if flag else 0, notx + (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.
Sorry about that. What was missing?
from 0 readers
Saved you an hour? Send a tip.
USDC or ETH on Base, Ethereum, Arbitrum and more. Keeps the notes free and the examples running.
Network
0xc783bc5c3fa14cEC3f09A22284bC91C5AF0d59e1
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
Next note