In the python document 2.4.3. Formatted string literals, it seems possible to write a star followed by an expression in a f-string’s {}
, but I cannot find how to use that.
What’s that and how I can use it? Is it documented somewhere?
To be exact, this is regarding "*" or_expr
part of the following BNF.
f_string ::= (literal_char | "{{" | "}}" | replacement_field)* replacement_field ::= "{" f_expression ["!" conversion] [":" format_spec] "}" f_expression ::= (conditional_expression | "*" or_expr) ("," conditional_expression | "," "*" or_expr)* [","] | yield_expression
I tried it in REPL, but it causes an error.
>>> l = [1, 2, 3] >>> f"{l}" '[1, 2, 3]' >>> f"{*l}" File "<stdin>", line 1 SyntaxError: can't use starred expression here
Advertisement
Answer
There are two alternatives for f_expression
: a comma separated list of or_expr
s, optionally preceded by asterisks, or a single yield_expression
. Note the yield_expression
does not allow an asterisk.
I assume the intention was that the comma-separated list alternative is only chosen when there’s at least one comma, but the grammar doesn’t actually say that. I feel like the repetition operator at the end should have been a +
instead of a *
.
So f"{*1}"
would be a syntax error because there’s an asterisk, but no comma. f"{*1,*2}"
is syntactically valid, but a type error because 1 and 2 aren’t iterable. f"{*[1], *[2]}"
is valid and acts the same as f"{1,2}"
. So the asterisk is allowed because it acts as the splat operator in tuples, which can be written without parentheses in f-expressions.
Note that using or_expr
as the operand to *
does not mean that a bitwise or-operator has to be used there – it just means that the bitwise or-operator is the first operator in the precedence-hierachy that would be allowed as an operand to *
. So it’s just about setting the precedence of prefix *
vs. other expressions. I believe or_expr
is consistently used as the operand to prefix *
everywhere in the grammar (that is, everywhere where prefix *
is followed by an expression as opposed to a parameter name).