Go deh!

Mainly Tech projects on Python and Electronic Design Automation.

Saturday, March 17, 2018

Or nested f-strings in python 3.6

Someone wrote some code to format the printing of a list of floats, which got me thinking...
In their video they did a great little history of formatting options in Python.
They then went on to consider how to format a list of floats but to n-decimal places.

In [4]:
```l = [x**.5 for x in range(1, 11)]
print('Default:', l)
```
```Default: [1.0, 1.4142135623730951, 1.7320508075688772, 2.0, 2.23606797749979, 2.449489742783178, 2.6457513110645907, 2.8284271247461903, 3.0, 3.1622776601683795]
```
In [5]:
```s = ', '.join(map(lambda x: f"{x:.3f}", l))
print(f'Their floats: [{s}]')
```
```Their floats: [1.000, 1.414, 1.732, 2.000, 2.236, 2.449, 2.646, 2.828, 3.000, 3.162]
```
I could easily see what they were doing but:
1. I didn't like the mixing of the use of list comprehensions and map
2. I immediatly thought: Could we do an f-string inside an f-string?

My nested f-string solution

A bit of thought produced this:
In [6]:
```l = [x**.5 for x in range(1, 11)]
print(f'''floats: [{", ".join(f"{x:.3f}" for x in l)}]''')
```
```floats: [1.000, 1.414, 1.732, 2.000, 2.236, 2.449, 2.646, 2.828, 3.000, 3.162]
```
The nest of the f-string does work! it isn't very clear code, but the f-string implementation is nestable.
Now the above uses an outer triple-quoted string to make the use of inner strings easier. It will work, however with all the same quotes but not in Jupyter notebook
Python 3.6.0a3 in idle gives this:
``````>>> print(f"floats: [{\", \".join(f\"{x:.3f}\" for x in l)}]")
floats: [1.000, 1.414, 1.732, 2.000, 2.236, 2.449, 2.646, 2.828, 3.000, 3.162]
>>>

``````
In Jupyter I get the following:
In [7]:
```print(f"floats: [{\", \".join(f\"{x:.3f}\" for x in l)}]")
```
```  File "", line 1
print(f"floats: [{\", \".join(f\"{x:.3f}\" for x in l)}]")
^
SyntaxError: f-string expression part cannot include a backslash
```
I guess I need to report this...

My code with the nesting removed

(I prefer comprehensions over the use of map)
In [8]:
```l = [x**.5 for x in range(1, 11)]
s = ", ".join(f"{x:.3f}" for x in l)
print(f'floats: [{s}]')
```
`floats: [1.000, 1.414, 1.732, 2.000, 2.236, 2.449, 2.646, 2.828, 3.000, 3.162]`