23

What is wrong with this piece of code?

dic = { 'fruit': 'apple', 'place':'table' }
test = "I have one {fruit} on the {place}.".format(dic)
print(test)

>>> KeyError: 'fruit'
1

3 Answers 3

43

Should be

test = "I have one {fruit} on the {place}.".format(**dic)

Note the **. format() does not accept a single dictionary, but rather keyword arguments.

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

5 Comments

Thanks, it works. Can you update the answer to explain why I have to add ** before the dictionary?
@bogdan, the ** indicates that the dictionary should be expanded to a list of keyword parameters. The format method doesn't take a dictionary as a parameter, but it does take keyword parameters.
@bogdan: Added two links to my answer. The reason basically is "because the documentation says so".
@bogdan That just tells Python that you are providing a dictionary to the function so that it can provide the values in the dictionary, rather than the dictionary itself. You can do the same when calling any function. If function 'f' takes the args 'a','b', and 'c', you could use dic = {'a':1,'b':2,'c':3} and call f(**dic).
The reason is that "I have one {0[fruit]} on the {0[place]}.".format(dic) works too - dic is the 0th positional argument here and you can access it's keys in the template.
11

There is ''.format_map() function since Python 3.2:

test = "I have one {fruit} on the {place}.".format_map(dic)

The advantage is that it accepts any mapping e.g., a class with __getitem__ method that generates values dynamically or collections.defaultdict that allows you to use non-existent keys.

It can be emulated on older versions:

from string import Formatter

test = Formatter().vformat("I have one {fruit} on the {place}.", (), dic)

Comments

1

You can use the following code too:

dic = { 'fruit': 'apple', 'place':'table' }
print "I have one %(fruit)s on the %(place)s." % dic

If you want to know more about format method use: http://docs.python.org/library/string.html#formatspec

6 Comments

The % operator shouldn't be used in new code according to the Python documentation.
Could you please give me a reference so i will be able to read more on this?
Thank you very much), will try to avoid using it from now
@Mark: % was meant to be deprecated in Python 3.1, but they never did. It won't go away soon (or probably not at all), so it's ok to still use it.
@Sven, good to know, thanks. Still I'd go with format first because it's recommended, second because it seems cleaner.
|

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.