3

here is a quick example of what I'm trying to do

box = {
    'colour': 'Red',
    'dimensions': {
        'width': '100px',
        'height': '333px',
     }
}

print "The box is %(colour)s, wide %(dimensions.width) and high %(dimensions.height)" %box

Is this possible with the standard library?

If not, what libraries would you recommend?

1

6 Answers 6

10
>>> box = {
        'colour': 'Red',
        'dimensions': {
            'width': '100px',
            'height': '333px',
         }
    }
>>> print "The box is {colour}, wide {dimensions[width]} and high {dimensions[height]}".format(**box)
The box is Red, wide 100px and high 333px
Sign up to request clarification or add additional context in comments.

3 Comments

If using the . dot notation in your strings is really important to you then there is a way you can do that as well.
i see that it works, but how does the dict unpacking work here? why don't the width and height need quotes around?
From the docs: 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__().
3

Yes. You've got it right, except that you should use {} instead of %().

2 Comments

example? and version of python?
{N} string formatting was introduced 2.4, and you were allowed to use {} instead of {0}, {1} (positional formatting) since python 2.7. Its use is encouraged above %(), especially in the 3.x series as the former is deprecated. print('Hello {}, this is {}'.format('world', 'python')) Also see the webpage: http://docs.python.org/2/library/string.html
2

...also, have a look at string templates, been around since 2.4

Example

>>> from string import Template
>>> s = Template('$who likes $what')
>>> s.substitute(who='tim', what='kung pao')
'tim likes kung pao'
>>> d = dict(who='tim')
>>> Template('Give $who $100').substitute(d)
Traceback (most recent call last):
[...]
ValueError: Invalid placeholder in string: line 1, col 10
>>> Template('$who likes $what').substitute(d)
Traceback (most recent call last):
[...]
KeyError: 'what'
>>> Template('$who likes $what').safe_substitute(d)
'tim likes $what'

Comments

0

Yes, but unfortunately only for Python3

http://docs.python.org/release/3.0.1/whatsnew/2.6.html#pep-3101

Edit:

Sorry, this feature also ported in python 2:

>>> import sys
>>> print 'Platform: {0.platform}\nPython version: {0.version}'.format(sys)
Platform: linux2
Python version: 2.7.1+ (r271:86832, Apr 11 2011, 18:05:24) 
[GCC 4.5.2]

1 Comment

Are you sure? I think this is supported in python 2.7 using the % operator, but I don't have a Python system to hand.
0

In an object oriented manner, you could have Box as an object and then override the __str__() and __unicode__() methods to print out the variables such as width and colour in a human-readable string.

Example:

class Box():
    def __init__(self, **kwargs):
        self.dimensions = (kwargs.get('width'), kwargs.get('height'),)
        self.colour = kwargs.get('colour')

    def __str__(self):
        return 'The box is {}, wide {}, and {} height'.format(
            self.dimensions[0], self.dimensions[1], self.colour)

and here is how you initiate the class:

a = Box(height='100px', width='100px', colour='Red')

and this is how you print it out:

print(a)

or

myvar = str(a)

Note: I put width and height in a tuple.

Comments

-1

Here is the solution I came up with, although the str.format methods are probably cleaner, add the following function and then use "...format string..." % flatten(box).

def flatten(d, key=None):
    r = d.copy()
    if key is not None:
        r = dict((key+"."+k, v) for k, v in r.iteritems())
    for k, v in r.items():
        if isinstance(v, dict):
            r.update(flatten(v, k))
            del r[k]
    return r

Here is an example:

>>> flatten(box)
{'dimensions.width': '100px', 'colour': 'Red', 'dimensions.height': '333px'}
>>> print "The box is %(colour)s, wide %(dimensions.width)s and high %(dimensions.height)s" % flatten(box)
The box is Red, wide 100px and high 333px

Comments

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.