Nested f-strings
I don't think formatted string literals allowing nesting (by nesting, I take it to mean f'{f".."}'
) is a result of careful consideration of possible use cases, I'm more convinced it's just allowed in order for them to conform with their specification.
The specification states that they support full Python expressions* inside brackets. It's also stated that a formatted string literal is really just an expression that is evaluated at run-time (See here, and here). As a result, it only makes sense to allow a formatted string literal as the expression inside another formatted string literal, forbidding it would negate the full support for Python expressions.
The fact that you can't find use cases mentioned in the docs (and only find test cases in the test suite) is because this is probably a nice (side) effect of the implementation and not it's motivating use-case.
Actually, with two exceptions: An empty expression is not allowed, and a lambda expression must be surrounded by explicit parentheses.
Nested f-strings?
Without context, this seems like an XY problem. You should probably use a dict or list instead of variables, based on How do I create variable variables? For example,
dict
>>> i, j = 1, 2
>>> a = {1: 1, 2: 2}
>>> f"{a[i]} + {a[j]} = 3"
'1 + 2 = 3'
list
>>> i, j = 0, 1 # list indexing starts at 0
>>> a = [1, 2]
>>> f"{a[i]} + {a[j]} = 3"
'1 + 2 = 3'
Nested f-strings in Python (Third nested f-string)
Quick fix
You were on the right track, using the new_line
variable together with str.join()
. To maintain the number of spaces, just include them in new_line
:
new_line = ' \n'
Further thinking
You may want to start using a templating engine, like Jinja.
Pros
- You don't need to concern yourself with (nested) f-strings
- The template string looks like your desired output (kinda WYSIWYG)
- Whitespace control is easy
Cons
- You'll probably have to spend some time learning how to use the templating engine
Your example, implemented with Jinja
To run the following code, you need to install the jinja2
package
import jinja2
user_dicts = { 'users': [ {'name': 'test1', 'pass': 'password1', 'permissions': [ {'access': 'yes', 'role': 'admin'}, {'access': 'yes', 'role': 'user'} ] }, {'name': 'test2', 'pass': 'password2', 'permissions': [ {'access': 'yes', 'role': 'admin'} ] } ] }
template_str = """
users = [
{% for user in users %}
{
name = "{{ user['name'] }}",
pass = "{{ user['pass'] }}",
permissions = [
{% for p in user['permissions'] %}
{ access = "{{ p['access'] }}", role = "{{ p['role'] }}" },
{% endfor %}
]
},
{% endfor %}
]
""".strip()
template = jinja2.Template(template_str, trim_blocks=True, lstrip_blocks=True)
users = template.render(user_dicts).replace("'", '"')
The template string template_str
is basically your desired output, plus some special tokens ({% for ... %}
, {% endfor %}
, {{ ... }}
). These tokens tell the engine how to "fill in the blanks".
How to fix SyntaxError: f-string: expressions nested too deeply in python 3.7.0?
You could use multi-line strings f"""This will work as expected with other nested strings '{3+5}'"""
Python 3 Nesting String format
Your "nested" format string needs to be formatted twice. Any curly braces you want to keep for the second time needs to be escaped in the first, thus {
becomes {{
and }
becomes }}
. Also, since you can't use the f
prefix twice, You can explicitly call format
for the second formatting.
What you're looking for is this:
for i in range(1, size + 1):
line = f"{i}" * i
print(f"{{0:>{size}}}".format(line))
So first string formatting turns f"{{0:>{size}}}"
into {0:>3}
, thus when reaching the explicit calling of format
you basically get print("{0:>3}".format(line))
.
Getting Error in python SyntaxError: f-string: expressions nested too deeply
I believe just just need to escape the curly brackets to make this work:
f'{{"requests":[{{"indexName":"New_Telemart","params":"query=Mobiles&maxValuesPerFacet=10&page="{i}"&highlightPreTag=__ais-highlight__&highlightPostTag=__%2Fais-highlight__&facets=%5B%22brand_name%22%2C%22categories%22%2C%22sale_price%22%2C%22total_rating_average%22%2C%22express_delivery%22%5D&tagFilters=&facetFilters=%5B%5B%22categories%3ASmartphones%22%2C%22categories%3AMobile%20%26%20Tablets%22%5D%5D"}}, {{"indexName":"New_Telemart","params":"query=Mobiles&maxValuesPerFacet=10&page=0&highlightPreTag=__ais-highlight__&highlightPostTag=__%2Fais-highlight__&hitsPerPage=1&attributesToRetrieve=%5B%5D&attributesToHighlight=%5B%5D&attributesToSnippet=%5B%5D&tagFilters=&analytics=false&clickAnalytics=false&facets=categories"}}]}}'
You can read the f-string documentation for more information
Nesting / escaping a f-string = (equal sign) expression
As said in the What's New In Python 3.8 document:
Added an
=
specifier to f-strings. An f-string such asf'{expr=}'
will
expand to the text of the expression, an equal sign, then the
representation of the evaluated expression.
So no, you can't do it that way(one shot) because the left side of =
will become a string. Use traditional f-string interpolation:
print(f'double({some_int}) = {double(some_int)}')
Output:
double(2) = 4
How can I dynamically pad a number in python f-strings?
Nested f-string:
>>> pad = 4
>>> i = 1
>>> f"foo-{i:>0{pad}}"
'foo-0001'
Related Topics
Python - Using the Multiply Operator to Create Copies of Objects in Lists
String Similarity Metrics in Python
@Csrf_Exempt Does Not Work on Generic View Based Class
How to Use a Multiprocessing Queue in a Function Called by Pool.Imap
"Private" (Implementation) Class in Python
How to Send an Xml Body Using Requests Library
Python: Excluding Modules Pyinstaller
How to Split/Partition a Dataset into Training and Test Datasets For, E.G., Cross Validation
Adding Headers to Requests Module
How to Sort a Pandas Dataframe by Index
How to Read One Single Line of CSV Data in Python
How to Use MySQLdb with Python and Django in Osx 10.6
How to Make Sessions Timeout in Flask
Add Column with Constant Value to Pandas Dataframe
Python Library 'Unittest': Generate Multiple Tests Programmatically