Re: [Python-ideas] Python-ideas Digest, Vol 131, Issue 106

On 31.10.2017 8:37, python-ideas-request@python.org wrote:
On Tue, Oct 31, 2017 at 3:50 PM, Ivan Pozdeev via Python-ideas python-ideas@python.org wrote:
On 30.10.2017 17:32, Guido van Rossum wrote:
This is a key example of a case where code speaks. Can you write an implementation of how you would want single() to work in Python code?
On Mon, Oct 30, 2017 at 2:49 AM, Ivan Pozdeev via Python-ideas <python-ideas@python.org mailto:python-ideas@python.org> wrote:
The initial post on the above link summarizes the suggested implementation pretty well.
|defsingle(i): try: ||v =i.next() |||exceptStopIteration:||||raiseException('No values')|||try: ||i.next() ||exceptStopIteration: ||returnv||else: ||raiseException('Too many values')| ||printsingle(name forname in('bob','fred')ifname=='bob')||| |
||
raise WhitespaceDamagedException from None
ChrisA
Thunderbird jerked on me big time. It never did anything like this before! Switched off Digest mode, individual messages aren't so complicated.
def single(i): try: v =i.next() except StopIteration: raise ValueError('No items') try: i.next() except StopIteration: return v else: raise ValueError('More than one item')
print single(name for name in('bob','fred') if name=='bob')

On Tue, Oct 31, 2017 at 5:18 PM, Ivan Pozdeev via Python-ideas python-ideas@python.org wrote:
raise WhitespaceDamagedException from None
Thunderbird jerked on me big time. It never did anything like this before! Switched off Digest mode, individual messages aren't so complicated.
def single(i): try: v =i.next() except StopIteration: raise ValueError('No items') try: i.next() except StopIteration: return v else: raise ValueError('More than one item')
print single(name for name in('bob','fred') if name=='bob')
Thanks :)
One small change: If you use next(i) instead of i.next(), your code should work on both Py2 and Py3. But other than that, I think it's exactly the same as most people would expect of this function.
ChrisA

On Tue, Oct 31, 2017 at 06:02:34PM +1100, Chris Angelico wrote:
def single(i): try: v =i.next() except StopIteration: raise ValueError('No items') try: i.next() except StopIteration: return v else: raise ValueError('More than one item')
print single(name for name in('bob','fred') if name=='bob')
Seems like an awfully complicated way to do by hand what Python already does for you with sequence unpacking. Why re-invent the wheel?
Thanks :)
One small change: If you use next(i) instead of i.next(), your code should work on both Py2 and Py3. But other than that, I think it's exactly the same as most people would expect of this function.
Not me. As far as I can tell, that's semantically equivalent to:
def single(i): result, = i return result
apart from slightly different error messages.

On Tue, Oct 31, 2017 at 6:46 PM, Steven D'Aprano steve@pearwood.info wrote:
On Tue, Oct 31, 2017 at 06:02:34PM +1100, Chris Angelico wrote:
One small change: If you use next(i) instead of i.next(), your code should work on both Py2 and Py3. But other than that, I think it's exactly the same as most people would expect of this function.
Not me. As far as I can tell, that's semantically equivalent to:
def single(i): result, = i return result
apart from slightly different error messages.
I saw the original code as being like the itertools explanatory functions - you wouldn't actually USE those functions, but they tell you what's going on when you use the simpler, faster, more compact form.
ChrisA

On Tue, Oct 31, 2017 at 10:01 AM, Chris Angelico rosuav@gmail.com wrote:
On Tue, Oct 31, 2017 at 6:46 PM, Steven D'Aprano steve@pearwood.info wrote:
On Tue, Oct 31, 2017 at 06:02:34PM +1100, Chris Angelico wrote:
One small change: If you use next(i) instead of i.next(), your code should work on both Py2 and Py3. But other than that, I think it's exactly the same as most people would expect of this function.
Not me. As far as I can tell, that's semantically equivalent to:
def single(i): result, = i return result
apart from slightly different error messages.
I saw the original code as being like the itertools explanatory functions - you wouldn't actually USE those functions, but they tell you what's going on when you use the simpler, faster, more compact form.
I wonder if that's more easily understood if you write it along these line(s):
(the_bob,) = (name for name in ('bob','fred') if name=='bob')
People need to learn about how to make a 1-tuple quite early on anyway, and omitting the parentheses doesn't really help there, AFAICT. Then again, the idiom looks even better when doing
a, b = find_complex_roots(polynomial_of_second_order)
Except of course that I couldn't really come up with a good example of something that is expected to find exactly two values from a larger collection, and the students are already coming into the lecture hall.
Or should it be
(a, b,) = find_complex_roots(polynomial_of_second_order)
?
––Koos

On 10/31/2017 09:54 AM, Koos Zevenhoven wrote:
On Tue, Oct 31, 2017 at 10:01 AM, Chris Angelico <rosuav@gmail.com mailto:rosuav@gmail.com>wrote:
On Tue, Oct 31, 2017 at 6:46 PM, Steven D'Aprano <steve@pearwood.info <mailto:steve@pearwood.info>> wrote: > On Tue, Oct 31, 2017 at 06:02:34PM +1100, Chris Angelico wrote: >> One small change: If you use next(i) instead of i.next(), your code >> should work on both Py2 and Py3. But other than that, I think it's >> exactly the same as most people would expect of this function. > > Not me. As far as I can tell, that's semantically equivalent to: > > def single(i): > result, = i > return result > > apart from slightly different error messages. I saw the original code as being like the itertools explanatory functions - you wouldn't actually USE those functions, but they tell you what's going on when you use the simpler, faster, more compact form.
I wonder if that's more easily understood if you write it along these line(s):
(the_bob,) = (name for name in ('bob','fred') if name=='bob')
There are (unfortunately) several ways to do it. I prefer one that avoids a trailing comma:
[the_bob] = (name for name in ('bob','fred') if name=='bob')

On Tue, Oct 31, 2017 at 11:24 AM, Petr Viktorin encukou@gmail.com wrote:
On 10/31/2017 09:54 AM, Koos Zevenhoven wrote:
I wonder if that's more easily understood if you write it along these line(s):
(the_bob,) = (name for name in ('bob','fred') if name=='bob')
There are (unfortunately) several ways to do it. I prefer one that avoids a trailing comma:
[the_bob] = (name for name in ('bob','fred') if name=='bob')
Maybe it's just me, but somehow that list-like syntax as an assignment target feels wrong in somewhat the same way that (1, 2).append(3) does.
––Koos PS. In your previous email, something (your email client?) removed the vertical line from the quoted Chris's email, so it looks like just an indented block. I wonder if a setting could fix that.

On Tue, Oct 31, 2017 at 12:18 PM Koos Zevenhoven k7hoven@gmail.com wrote:
On Tue, Oct 31, 2017 at 11:24 AM, Petr Viktorin encukou@gmail.com wrote:
On 10/31/2017 09:54 AM, Koos Zevenhoven wrote:
I wonder if that's more easily understood if you write it along these line(s):
(the_bob,) = (name for name in ('bob','fred') if name=='bob')
There are (unfortunately) several ways to do it. I prefer one that avoids a trailing comma:
[the_bob] = (name for name in ('bob','fred') if name=='bob')
Maybe it's just me, but somehow that list-like syntax as an assignment target feels wrong in somewhat the same way that (1, 2).append(3) does.
Off topic: why can't we simply allow something like this:
(the_bob) = (name for name in ('bob','fred') if name=='bob')
Why does Python treat the parenthesis at the LHS as grouping parens? operators are not allowed anyway; (a + (b + c)) = [1] is syntax error.
Currently
(x) = 1
works, but I can't see why should it.
Elazar

On Tue, Oct 31, 2017 at 10:31:50AM +0000, אלעזר wrote:
Off topic: why can't we simply allow something like this:
(the_bob) = (name for name in ('bob','fred') if name=='bob')
Parens don't make a tuple. They are just for grouping. If you want a tuple, you need a comma:
the_bob, = ...
with or without the parens. It would be terribly surprising if (x) was a sequence on the left hand side but not on the right hand side of an assignment.
Why does Python treat the parenthesis at the LHS as grouping parens? operators are not allowed anyway; (a + (b + c)) = [1] is syntax error.
a, (b, c), d = [1, "xy", 2]
Currently
(x) = 1
works, but I can't see why should it.
Why shouldn't it?
Its just a trivial case of the fact that the left hand side can be certain kinds of expressions, some of which require parens:
(spam or ham)[x] = value
There are lots of possible expressions allowed on the LHS, and no good reason to prohibit (x) even though its pointless.
participants (6)
-
Chris Angelico
-
Ivan Pozdeev
-
Koos Zevenhoven
-
Petr Viktorin
-
Steven D'Aprano
-
אלעזר