I would like to use Python string's format()
to act as a quick and dirty template. However, the dict
that I would like to use has keys which are (string representations) of integers. a simplified example follows:
s = 'hello there {5}'
d = {'5': 'you'}
s.format(**d)
the above code throws the following error:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: tuple index out of range
is it possible to do the above?
Python Dictionary keys() The keys() method extracts the keys of the dictionary and returns the list of keys as a view object.
Second, a dictionary key must be of a type that is immutable. For example, you can use an integer, float, string, or Boolean as a dictionary key. However, neither a list nor another dictionary can serve as a dictionary key, because lists and dictionaries are mutable.
No, there is no guaranteed order for the list of keys returned by the keys() function. In most cases, the key list is returned in the same order as the insertion, however, that behavior is NOT guaranteed and should not be depended on by your program.
We've established that it won't work, but how about a solution:
Although str.format
won't work in this case, funnily enough the old %
formatting will. This is not recommended, but you did ask for a quick and dirty template.
>>> 'hello there %(5)s' % {'5': 'you'}
'hello there you'
Do note though that this won't work for integer keys.
>>> 'hello there %(5)s' % {5: 'you'}
Traceback (most recent call last):
File "<pyshell#1>", line 1, in <module>
'hello there %(5)s' % {5: 'you'}
KeyError: '5'
I love the idea of extending the Formatter so that it allows arbitrary field names (integers, field names with a colon etc). An implementation might look like this:
import string, re
class QuFormatter(string.Formatter):
def _quote(self, m):
if not hasattr(self, 'quoted'):
self.quoted = {}
key = '__q__' + str(len(self.quoted))
self.quoted[key] = m.group(2)
return '{' + m.group(1) + key + m.group(3) + '}'
def parse(self, format_string):
return string.Formatter.parse(self,
re.sub(r'{([^}`]*)`([^}`]*)`([^}]*)}', self._quote, format_string))
def get_value(self, key, args, kwargs):
if key.startswith('__q__'):
key = self.quoted[key]
return string.Formatter.get_value(self, key, args, kwargs)
Usage:
d = {'5': 'you', '6': 'me', "okay":1, "weird:thing!": 123456}
print QuFormatter().format(
'hello there {`5`} {`6`:20s}--{okay}--{`weird:thing!`:20,d}',
**d)
So fields in backticks are treated literally.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With