<div dir="ltr"><div class="gmail_quote"><div dir="ltr">On Wed, Oct 12, 2016 at 11:26 PM David Mertz <<a href="mailto:mertz@gnosis.cx">mertz@gnosis.cx</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr" class="gmail_msg"><div class="gmail_extra gmail_msg"><div class="gmail_quote gmail_msg">On Wed, Oct 12, 2016 at 12:38 PM, אלעזר <span dir="ltr" class="gmail_msg"><<a href="mailto:elazarg@gmail.com" class="gmail_msg" target="_blank">elazarg@gmail.com</a>></span> wrote:<br class="gmail_msg"><blockquote class="gmail_quote gmail_msg" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><p dir="ltr" class="gmail_msg">What is the intuition behind [1, *x, 5]? The starred expression is replaced with a comma-separated sequence of its elements.</p></blockquote></div></div></div><div dir="ltr" class="gmail_msg"><div class="gmail_extra gmail_msg"><div class="gmail_quote gmail_msg"><div class="gmail_msg">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:</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">     a, *b, c = range(10)</div><div class="gmail_msg"><br class="gmail_msg"></div></div></div></div></blockquote><div><br></div><div>It's not exactly "analogy" as such - it is the dual notion. Here you are using the "destructor" (functional terminology) but we are talking about "constructors". But nevermind.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr" class="gmail_msg"><div class="gmail_extra gmail_msg"><div class="gmail_quote gmail_msg"><div class="gmail_msg"></div><div class="gmail_msg">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:</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg"><div class="gmail_msg">    >>> *b = range(10)</div><div class="gmail_msg">    SyntaxError: starred assignment target must be in a list or tuple<br class="gmail_msg"></div></div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">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.</div><div class="gmail_msg"><br class="gmail_msg"></div></div></div></div></blockquote><div><br></div><div>But that's not a uniform treatment. It might have good reasons from readability point of view, but it is an explicit exception for the rule. The desired behavior would be equivalent to</div><div><br></div><div>    b = tuple(range(10))</div><div><br></div><div>and yes, there are Two Ways To Do It. I would think it should have been prohibited by PEP-8 and not by the compiler. Oh well.</div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr" class="gmail_msg"><div class="gmail_extra gmail_msg"><div class="gmail_quote gmail_msg"><div class="gmail_msg"></div><div class="gmail_msg">What seems to be wanted with `<span style="font-size:11.2px" class="gmail_msg">[*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).</span></div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">We do have a possibility of writing this:</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">    >>>  [(*stuff,) for stuff in [range(-5,-1), range(5)]]</div><div class="gmail_msg">    [(-5, -4, -3, -2), (0, 1, 2, 3, 4)] </div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">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:</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg"><div class="gmail_msg">    >>> [item for seq in [range(-5,-1), range(5)] for item in seq]</div><div class="gmail_msg">    [-5, -4, -3, -2, 0, 1, 2, 3, 4]</div></div><div class="gmail_msg"><br class="gmail_msg"></div></div></div></div></blockquote><div><br></div><div>The distinction between (x) and (x,) is already deep in the language. It has nothing to do with this thread</div><div><br></div><div><div>>>> [1, *([2],), 3]</div><div>[1, [2], 3]</div><div>>>> [1, *([2]), 3]</div><div>[1, 2, 3]</div></div><div><br></div><div>So there. Just like in this proposal.</div><div><br></div><div>Elazar.</div></div></div>