1

I was surprised that python's percent-style formatting won't accept a list and seems to only accept tuples. What is special about tuples here? Why does the list throw the error?

In [1]: '%s %s' % ('hello', 'kilojoules')                                                     
Out[1]: 'hello kilojoules'

In [2]: '%s %s' % ['hello', 'kilojoules']                                                     
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-2-764f27542c69> in <module>
----> 1 '%s %s' % ['hello', 'kilojoules']

TypeError: not enough arguments for format string
1
  • 1
    Trivial answer: because that's how it's specified. Why this decision was made is off-topic for Stack Overflow; maybe try comp.lang.python? Commented Jun 24, 2019 at 1:07

3 Answers 3

3

The way you are using to format strings is a special syntax. In the list example you show, it is converting the non-tuple (a list) into a string before attempting to use it for formatting purposes.

You can do what you're trying to do by using the format method.

In [1]: "{} {}".format(*['hello', 'kilojoules'])

Doing it this way is recommended anyway, as it is preferred.

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

1 Comment

It may not be deprecated, but it is specifically discouraged in the docs. Unless you are maintaining an old code base, you should stick to either str.format or f-string literals
2

Also, with the latest updates in python3.6, you can use f-Strings like this:

> great = "hello"
> name = "kilojoules"

> f"{great} {name}"
'hello kilojoules'

This website gives a good summary of the different ways to do it.

Comments

1

The documentation (https://python-reference.readthedocs.io/en/latest/docs/str/formatting.html) answers your question directly: "If format specifier requires a single argument, values may be a single non-tuple object. Otherwise, values must be a tuple with exactly the number of items specified by the format string, or a single mapping object (for example, a dictionary)." A list is neither, so it won't do.

Like others have pointed out, you could just use .format for a more modern approach, or even the still more modern f-string, which is as concise as your original example:

one_way = '{} {}'.format(*['hello', 'kilojoules'])
lst = ['hello', 'kilojoules']
another_way = f'{lst[0]} {lst[1]}'

2 Comments

Your example of the 'more modern f string' is missing the f bit :P
Thanks @shadow - nasty oversight :); I blame the painful way of moving code between my IDE and SO (although I'm really the only one to blame); fixed it.

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.