19

Say I have a function

def foo(): return [1, 2, 3]

I want to interpolate the result of the function into a string to get "001 002 003". I've tried this:

f"{*foo():03d 03d 03d}"

But it produced SyntaxError: can't use starred expression here. Can I do this using an f-string?

2
  • 3
    f"{' '.join(map('{:03d}'.format, foo()))}"? Commented Jan 27, 2017 at 14:43
  • 2
    The suggestion works, but the f-string is redundant and the syntax verbose. One can just use the similar answer by @ev-kounis, without f-string. It seems f-strings do not improve the printing of lists. Commented Feb 20, 2018 at 9:52

5 Answers 5

7

is this what you are looking for?

str_repr = ' '.join(map('{:03d}'.format, foo()))
print(str_repr)  # prints: 001 002 003

maybe the best thing about this solution is that it works with any list length and with minimal tweaking you can change the output format too.

Sign up to request clarification or add additional context in comments.

1 Comment

This works, but it does not make use of f-strings as requested. It may indeed be the best available Python solution, but it is verbose. I wish something like this f"{foo():03d}" would thread over the list.
7

Starred expressions are only allowed in few specific contexts, such as function calls, list/tuple/set literals, etc. An f-string placeholder is not one of them, apparently. You could format each element individually and join the strings, e.g.:

lst = foo()
s = ' '.join(f'{x:03d}' for x in lst)  # '001 002 003'

Generally, to format multiple values you have to use a separate placeholder for each value.

Comments

3

The * operator (similar rules exist for **) can only be used inside:

  • a function call: foo(*bar)
  • a list, tuple, or set literal: ['foo', *bar]
  • an assignment: foo, *bar = range(10)

It is not an expression and can therefore not be used inside the braces of f-strings.

Comments

1

For lists, f-strings do not seem to add much to what was already possible without them. An alternative, slightly simpler, solution without f-strings and without .join, which works for any list length, is the following

a = foo()
str_repr = ("{:03d} "*len(a)).format(*a)
print(str_repr)  # prints: 001 002 003

Comments

1

You can also use the zfill method instead:

s_repr=" ".join([str(x).zfill(3) for x in foo()]) #not very PEP8 =S

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.