1
print '%d:%02d' % divmod(10,20)

results in what I want:

0:10

However

print '%s %d:%02d' % ('hi', divmod(10,20))

results in:

Traceback (most recent call last):
  File "<pyshell#6>", line 1, in <module>
    print '%s %d:%02d' % ('hi', divmod(10,20))
TypeError: %d format: a number is required, not tuple

How do I fix the second print statement so that it works?

I thought there was a simpler solution than

m = divmod(10,20)
print m[0], m[1]

or using python 3 or format().

I feel I'm missing something obvious

Martijn Pieters
  • 963,270
  • 265
  • 3,804
  • 3,187
foosion
  • 7,317
  • 24
  • 63
  • 98
  • from: http://stackoverflow.com/questions/1455602/printing-tuple-with-string-formatting-in-python print "this is a tuple: %s" % (divmod(10,20),) – sihrc Jul 25 '13 at 20:58
  • I think was a good question. Nothing obvious about it! Pretty subtle, in my opinion. Very informative. – Jiminion Jul 26 '13 at 01:10

3 Answers3

5

You are nesting tuples; concatenate instead:

print '%s %d:%02d' % (('hi',) + divmod(10,20))

Now you create a tuple of 3 elements and the string formatting works.

Demo:

>>> print '%s %d:%02d' % (('hi',) + divmod(10,20))
hi 0:10

and to illustrate the difference:

>>> ('hi', divmod(10,20))
('hi', (0, 10))
>>> (('hi',) + divmod(10,20))
('hi', 0, 10)

Alternatively, use str.format():

>>> print '{0} {1[0]:d}:{1[1]:02d}'.format('hi', divmod(10, 20))
hi 0:10

Here we interpolate the first argument ({0}), then the first element of the second argument ({1[0]}, formatting the value as an integer), then the second element of the second argument ({1[1]}, formatting the value as an integer with 2 digits and leading zeros).

Martijn Pieters
  • 963,270
  • 265
  • 3,804
  • 3,187
1
print '%s %d:%02d' % ('hi',divmod(10,20)[0], divmod(10,20)[1])
                       ^         ^                 ^
                       1         2                 3

Parentheses with commas indicate tuples, parens with concatenation (+) will return strings.

You need a 3-tuple for 3 inputs as shown

Stephan
  • 14,314
  • 7
  • 33
  • 60
  • @MartijnPieters you're faster than me, hold on – Stephan Jul 25 '13 at 20:56
  • You were a little too fast to post and not try first. :-) – Martijn Pieters Jul 25 '13 at 20:58
  • `'hi' + divmod(10,20)` -> `TypeError: cannot concatenate 'str' and 'tuple' objects` – RussW Jul 25 '13 at 20:58
  • @RussW I know, What i said doesn't contradict that – Stephan Jul 25 '13 at 21:00
  • @MartijnPieters yes, but i couldn't think of another one that didn't copy yours. Otherwise i would have posted what you did, at least it works, its just not accept-worthy – Stephan Jul 25 '13 at 21:08
  • @Stephan I like that you fixed it though – RussW Jul 25 '13 at 21:09
  • +1 for getting something that worked. I had to punt my answer and retreat in shame.... :) – Jiminion Jul 26 '13 at 01:16
  • 1
    @Jim giving up is the smart thing to do when MP posts an answer, but I STRIDE FORTH with a UNIQUE and much less optimal answer! – Stephan Jul 26 '13 at 02:32
  • Other answers can help to understand the problem better. I still am puzzled that ((('hi',) + divmod(10,20))) also works. – Jiminion Jul 26 '13 at 02:42
  • @Jim he is concatenating 2 tuples, one of em says 'hi' the other one is a pair – Stephan Jul 26 '13 at 02:57
  • Yes, but both (('hi',) + divmod(10,20)) AND ((('hi',) + divmod(10,20))) work. I'm definitely at the shallow end of the pool when it comes to python tuples.... – Jiminion Jul 26 '13 at 03:05
  • You are just grouping statements now; *just* a pair if parenthesis does not make a tuple. It is the *comma* that makes a tuple, actually. Parenthesis just make things unambiguous for the parser. See http://docs.python.org/2/reference/expressions.html#expression-lists – Martijn Pieters Jul 26 '13 at 06:40
0

You're passing a string and a tuple to the format's tuple, not a string and two ints. This works:

print '%s %d:%02d' % (('hi',) + divmod(10,20))

There is a tuple concatenation.

Paulo Bu
  • 28,366
  • 6
  • 72
  • 72