I think this is for people who already know Python, and just need a quick memory aid. I agree for a complete and correct reference I would recommend the documentation, as you said.
A proper cheatsheet takes liberties for the sake of achieving both brevity and comprehensiveness at the same time.
While I agree the notation is a bit weird, I disagree that there is any standard notation for types. The Python docs in particular fail for exactly one of the things I like about TFA - it tells you the type of the output of each function in its angle-bracketed style.
Take, for example, the definition of the operation s[i:j] in the Python docs: the result is "slice of s from i to j". Is that the same type as the input? Is it an iterator? No information.
I doubt most people are confused about the output, but a reference is specifically for people who are uncertain about how a function works.
In one of your math courses you'll eventually run across what they call "set builder notation.
The notation for this is a decent example that shouldn't be too hard to follow. What it's basically saying is
{2x: x∈[1,10)}
with the implication that x is an integer. We usually read the colon (or sometimes a vertical bar) as "such that". I know my explanation is somewhat lacking, but you can probably see the parallels there. You'll probably get to it this year or next.
I'm very aware of set builder notation, and also not a fan. I mean it beats a lot of other things mathematicians were probably doing before they agreed to it, but it's still not ideal in my eyes.
My example (formatted again below), is probably an interesting middle ground, because both the left and right are only mildly interesting. While most often (not always) in math I've seen the right be "trivial".
trivial right: { 2x : x ∈ ℝ }
mildly interesting right: { 2x : x ∈ [1,10) }
complex right: { 2x : x ∈ [0, ∞].filter(...) }
In the top two cases, things aren't so bad. But as we digress to the third case I fear we'd be better of like:
[0, ∞].filter(...).map(|x| 2x)
This is generally how I'd solve the issue. I've made a point of avoiding talking about nested array comprehensions, since these get completely impossible to reason about statically for me.
EDIT: Just because I' on a bit of a rant ATM, I might as well complete it...
In Rust we also have where clauses, however you still must at least introduce the name up front. For example:
fn foo<A>(..., a: A, ...) where A: ...
This solves the problem of name resolution in my head while I try and read this function, since there's always a namespace you're operating within. Without the leading `<A>` I'd be left wondering WTF `a: A` means.
As a person who often struggled in math for perhaps many reasons, this was a common issue for me.
First you define things, then you use them.
No other rule makes sense generally, and I challenge anyone to prove me wrong.
Now is a simple set like { 2x : x ∈ ℝ } going to confuse me, probably not... but when variables are just thrown around all willy nilly, I get confused pretty quick.
I never understood list comprehensions, and was always slightly resentful of (in my mind) their illogical ordering until I realized they were mimicking mathematical expressions.
I wouldn't call this a functional argument, per se, although many functional languages encourage the kind of syntax I'm advocating for here. And some may not...
Basically I write things like `data.map(|x| ...).filter(|x| ...)`, or just `data.fold(|x| ...)` and I'm quite happy.
The <thing> notation is pretty confusing and I find myself using my knowledge of python to understand what half of the examples are teaching rather than the other way around.
A good way of specifying variable types in sample code is with Python’s native type hint syntax[0].
Using angle brackets is an option, but it results in invalid syntax (confusing to beginner programmers) and is used by languages such as TypeScript and Swift to signify generics (confusing to established engineers coming from those languages).
It looks more like an XML cheatsheet at first glance.
I work in python full-time for a living, and found myself having to re-examine several times to make sense of this wacky, non-standard notation.
-------
Edit:
Keep in mind there's a standard way to represent these options in a clear, consistent manner (lists, sequences, optional args).
No need to re-invent something that's hard to read and understand.
See: https://docs.python.org/3/library/stdtypes.html#sequence-typ...