I have been examining some of my string format options using the new f-string format. I routinely need to unpack lists and other iterables of unknown length. Currently I use the following...
>>> a = [1, 'a', 3, 'b']
>>> ("unpack a list: " + " {} "*len(a)).format(*a)
'unpack a list: 1 a 3 b '
This, albeit a bit cumbersome, does the job using pre-3.6 .format notation. The new f-string format option is interesting given runtime string concatenation. It is the replication of the number of {} that I am having problems with. In my previous example, I simply created the necessary structure and unpacked within the .format() section.
Attempts to do this yielded one variant that worked, however:
>>> 'unpack a list' f' {{*a}}'
'unpack a list {*a}'
This works but leaves opening and closing braces {, } present:
>>> 'unpack a list' f' { {*a} }'
"unpack a list {1, 3, 'a', 'b'}"
This made the look and syntax better, since the evaluation, apparently, is from left to right. This, however, still left the enclosing curly brackets present:
>>> f'unpack a list { {*a} }'
"unpack a list {1, 3, 'a', 'b'}"
{a}
Perhaps, I was overthinking the whole procedure and hoping for some form of automatic unpacking. This simply yielded the list representation with the curly brackets being replaced with []
:
>>> f'unpack a list {a}'
"unpack a list [1, 'a', 3, 'b']"
What is required to suppress the curly brackets in variant (2) above, or must I keep using the existing .format()
method? I want to keep it simple and use the new capabilities offered by the f-string and not revert back beyond the python versions which pre-date what I am currently comfortable with. I am beginning to suspect that f'strings' do not offer a complete coverage of what is offered by its .format()
sibling. I will leave it at that for now, since I haven't even ventured into the escape encoding and the inability to use \ in an f-string. I have read the PEP and search widely, however, I feel I am missing the obvious or what I wish for is currently not possible.
EDIT several hours later:
str(a)[1:-2]
I did find this variant which will serve for some cases that I need
f'unpack a list: {str(a)[1:-2]}'
"unpack a list: 1, 'a', 3, 'b"
But the slicing is little more than a convenience and still leaves the string quotes around the resultant.
a = np.arange(10)
print(f"{*a,}")
(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
Unpacking with trailing comma.
Just add a comma after the unpacked list.
>>> a = [1, 2, 3]
>>> print(f"Unpacked list: {*a,}")
Unpacked list: (1, 2, 3)
There is a longer explanation to this syntax in this thread.
With this solution is that we do not have much control over the output formatting. We are stuck with whatever format
returns, which is actually (and suprisingly) the result from tuple.__repr__
. So the parenthesis that we get might be misleading, since we actually had a list, and not a tuple.
If this is too bad to put up with, I would recommend using the approach suggested by Zero Piraeus:
>>> a = [1, 2, 3]
>>> print(f'Unpacked list: {" ".join(str(i) for i in a)}')
This gives us the flexibility to format the list as we wish.