This is a great article. Thanks for writing it!
It’s a perfect example of a language feature that many of us use from time to time, but also either don’t or barely understand what’s going on under the hood.
Glad that you found it useful
Clear, concise, to the point. Full marks!
I also liked it very much. Just an excellent presentation of a surprising if not esoteric technical topic. Thanks.
Just a little nit, but args in def fn(*args): will actually be a tuple and not a list (so you can’t push or pop from it).
Good catch, thank you. I’ll update it!
I believe it’s also most correct to say that * works with any iterable and ** works with any mapping — that’s a much broader scope of things than just list and dict.
I really wish Python adopted the ... syntax over using * for instance:
Having a prepended unary operator that also doubles as a multiplication, can be a bit confusing
i agree that reusing syntax can be confusing, but on the other hand a complex syntax is also confusing.
your suggestion suffers from the same problem though: a literal ... is a built-in singleton in python, also known as Ellipsis:
it’s typically used for complex slicing (math libraries) and in type annotation stubs (e.g. typing.overload and pyi files)
Yeah, they already made this bed years ago
This is a little bit of a nitpick to an otherwise very good article, but I was a little surprised the article didn’t mention that ** is also the “raise to the power” operator as well as the multiplication operator.
Good point. Also, beyond numeric multiplication, * is used more generally as a shorthand for “repeat” on multiple data types, so that "-" * 30 means repeat the string "-" 30 times to create a 30-char horizontal rule string, and  * 30 means repeat the list  30 times to make a 30-element list of zeroes.
"-" * 30
 * 30
When I’m explaining it to people newer to Python I generally avoid names like “power operator” or “multiplication operator” or”addition operator” and instead just focus on the symbol, because operator overloading means there’s no single universal semantic meaning for any of these operators. So + is an addition operator on some types and a concatenation operator on others; * is multiplication on some types, repetition on others, and so on. Better to avoid trying to stick one and only one default meaning onto them.
10 years of python and I never knew about that last one! That could actually be really handy, thanks for the article!