On Wed, Oct 12, 2016 at 12:38 PM, אלעזר <elazarg@gmail.com> wrote:

What is the intuition behind [1, *x, 5]? The starred expression is replaced with a comma-separated sequence of its elements.

I've never actually used the `[1, *x, 5]` form.  And therefore, of course, I've never taught it either (I teach Python for a living nowadays).  I think that syntax already perhaps goes too far, actually; but I can understand it relatively easily by analogy with:

     a, *b, c = range(10)

But the way I think about or explain either of those is "gather the extra items from the sequence." That works in both those contexts.  In contrast:

    >>> *b = range(10)
    SyntaxError: starred assignment target must be in a list or tuple

Since nothing was assigned to a non-unpacked variable, nothing is "extra items" in the same sense.  So failure feels right to me.  I understand that "convert an iterable to a list" is conceptually available for that line, but we already have `list(it)` around, so it would be redundant and slightly confusing.

What seems to be wanted with `[*foo for foo in bar]` is basically just `flatten(bar)`.  The latter feels like a better spelling, and the recipes in itertools docs give an implementation already (a one-liner).

We do have a possibility of writing this:

    >>>  [(*stuff,) for stuff in [range(-5,-1), range(5)]]
    [(-5, -4, -3, -2), (0, 1, 2, 3, 4)] 

That's not flattened, as it should not be.  But it is very confusing to have `[(*stuff) for stuff in ...]` behave differently than that.  It's much more natural—and much more explicit—to write:

    >>> [item for seq in [range(-5,-1), range(5)] for item in seq]
    [-5, -4, -3, -2, 0, 1, 2, 3, 4]