# [Python-ideas] "given" vs ":=" in list comprehensions

Andre Roberge andre.roberge at gmail.com
Sat May 12 20:34:33 EDT 2018

``` Sorry for chiming in so late; I was lurking using google groups and had to
subscribe to post - hence this new thread.

I gather that *where* has been discarded as a possible new keywords given
its use as a function in numpy (
https://docs.scipy.org/doc/numpy-1.14.0/reference/generated/numpy.where.html)
...  Still, I will include it below for completeness (and as I think it
reads better than the other choices)

Here are two sets of two examples illustrating a situation that I have not
seen before, and which read (to me) much better when using a keyword (given
or where) than a symbol (:=). Furthermore, the position of the temporary
assignment can, in my opinion, be done differently and help in making the
code clearer.

First example: single temporary assignment, done four different ways.

1) using :=

real_roots = [ (-b/(2*a) + (D:= sqrt( (b/(2*a))**2 - c/a), -b/(2*a) - D)
for a in range(10)
for b in range(10)
for c in range(10)
if D >= 0]

2) using *given* at the very end

real_roots = [ (-b/(2*a) + D, -b/(2*a) - D)
for a in range(10)
for b in range(10)
for c in range(10)
if D >= 0
given D= sqrt( (b/(2*a))**2 - c/a)]

3) using *given* before the iterations

real_roots = [ (-b/(2*a) + D, -b/(2*a) - D)
given D= sqrt( (b/(2*a))**2 - c/a)
for a in range(10)
for b in range(10)
for c in range(10)
if D >= 0]

4) using *where* before the iterations  (which would be my preferred choice
if it were available)

real_roots = [ (-b/(2*a) + D, -b/(2*a) - D)
where D= sqrt( (b/(2*a))**2 - c/a)
for a in range(10)
for b in range(10)
for c in range(10)
if D >= 0]

Second example: multiple assignments.

When we have multiple temporary assignments, the situation can be more
complicated.  In the following series of examples, I will start in reverse
order compared to above.

5) using *where* before the iterations

real_roots2 = [ (-b/(2*a) + D, -b/(2*a) - D)
where D= sqrt( (b/(2*a))**2 - c/a)
where c = c_values/100
for c_values in range(1000)
if D >= 0]

6) using *given* before the iterations

real_roots2 = [ (-b/(2*a) + D, -b/(2*a) - D)
given D= sqrt( (b/(2*a))**2 - c/a)
given c = c_values/100
for c_values in range(1000)
if D >= 0]

7) using *given* at the very end

real_roots2 = [ (-b/(2*a) + D, -b/(2*a) - D)
for c_values in range(1000)
if D >= 0
given D= sqrt( (b/(2*a))**2 - c/a)
given c = c_values/100]

8) Using :=

real_roots2 = [  ( -b/(2*a) + (D:= sqrt( (b/(2*a))**2 -
(c:=c_values/100)/a),
-b/(2*a) - D)
for c_values in range(1000)
if D >= 0]

I find this last version extremely difficult to understand compared with
the others where a keyword is used.  Perhaps it is because I do not fully
understand how := should be used...

Finally ... if "where" cannot be used, given the very special status of
such temporary assignments, could "where_" (with a trailing underscore) be
considered? I would argue that any word followed by an underscore would be
more readable than a compound symbol such as ":=".

André
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20180512/f477a9c5/attachment-0001.html>
```