5

What is the proper way to format dict keys in string?

When I do this:

>>> foo = {'one key': 'one value', 'second key': 'second value'}
>>> "In the middle of a string: {foo.keys()}".format(**locals())

What I expect:

"In the middle of a string: ['one key', 'second key']"

What I get:

Traceback (most recent call last):
  File "<pyshell#4>", line 1, in <module>
    "In the middle of a string: {foo.keys()}".format(**locals())
AttributeError: 'dict' object has no attribute 'keys()'

But as you can see, my dict has keys:

>>> foo.keys()
['second key', 'one key']
MSeifert
  • 145,886
  • 38
  • 333
  • 352
Narann
  • 819
  • 2
  • 8
  • 20

4 Answers4

8

You can't call methods in the placeholders. You can access properties and attributes and even index the value - but you can't call methods:

class Fun(object):
    def __init__(self, vals):
        self.vals = vals

    @property
    def keys_prop(self):
        return list(self.vals.keys())

    def keys_meth(self):
        return list(self.vals.keys())

Example with method (failing):

>>> foo = Fun({'one key': 'one value', 'second key': 'second value'})
>>> "In the middle of a string: {foo.keys_meth()}".format(foo=foo)
AttributeError: 'Fun' object has no attribute 'keys_meth()'

Example with property (working):

>>> foo = Fun({'one key': 'one value', 'second key': 'second value'})
>>> "In the middle of a string: {foo.keys_prop}".format(foo=foo)
"In the middle of a string: ['one key', 'second key']"

The formatting syntax makes it clear that you can only access attributes (a la getattr) or index (a la __getitem__) the placeholders (taken from "Format String Syntax"):

The arg_name can be followed by any number of index or attribute expressions. An expression of the form '.name' selects the named attribute using getattr(), while an expression of the form '[index]' does an index lookup using __getitem__().


With Python 3.6 you can easily do this with f-strings, you don't even have to pass in locals:

>>> foo = {'one key': 'one value', 'second key': 'second value'}
>>> f"In the middle of a string: {foo.keys()}"
"In the middle of a string: dict_keys(['one key', 'second key'])"

>>> foo = {'one key': 'one value', 'second key': 'second value'}
>>> f"In the middle of a string: {list(foo.keys())}"
"In the middle of a string: ['one key', 'second key']"
MSeifert
  • 145,886
  • 38
  • 333
  • 352
0
"In the middle of a string: {}".format(list(foo.keys()))
BoreBoar
  • 2,619
  • 4
  • 24
  • 39
  • 4
    Please add a description of what?, why? and how? your code does. Someone who can understand it without an explanation doesn't need the code, either. – jpaugh Aug 17 '17 at 18:16
0
"In the middle of a string: {}".format([k for k in foo])
Ankush G
  • 989
  • 9
  • 14
  • 2
    You should try and explain your answers rather than just leaving a one liner of code with no context, it will help this asker and future visitors to the page – Wolfie Aug 17 '17 at 22:18
0

As it was said by others above you cannot do it in the way you would prefer, here are additional information to follow python string format calling a function

Pablito
  • 1
  • 1
  • 4