Reputation: 31
Code that I wrote:
def ball(f):
py_ball = f * 5
u_ball = py_ball / 10
return py_ball, u_ball
print("py ball: {}, u ball: {}".format(ball(100)))
When I use str.format
, it throws an exception:
Traceback (most recent call last): File "rear.py", line 5, in print("py ball: {}, u ball: {}".format(ball(100))) IndexError: tuple index out of range
But if I use %
formatting:
print("py ball: %d, u ball: %d" % ball(100))
it works just fine and produces:
py ball: 500, u ball: 50
Upvotes: 3
Views: 99
Reputation: 1121594
str.format()
takes separate arguments for each slot, while %
accepts a tuple or a single value. ball()
returns a tuple, and that's a single argument as far as str.format()
is concerned. Because your template has 2 slots, there is an argument missing for that second slot.
You have two options: Either accept a single argument for .format()
and use formatting instructions to extract the nested elements, or pass in the tuple as separate arguments.
The latter can be done with the *expr
call notation:
print("py ball: {}, u ball: {}".format(*ball(100)))
but the formatting specification lets you also address tuple elements:
print("py ball: {0[0]}, u ball: {0[1]}".format(ball(100)))
I used explicit numbering here to indicate that just one argument is expected, in position 0
; 0[0]
takes the first element of the tuple, 0[1]
takes the second.
Upvotes: 6
Reputation: 15300
The return value of ball()
is a single value - a tuple.
When you call "...".format(ball(100))
you are passing that single value to a function that will eventually want two values.
When you call "..." % ball(100)
you are supplying a tuple to the %
operator, which expects a tuple!
Not surprisingly, it works in the second case and fails in the first case.
Try using the splat operator to flatten the tuple into the arguments of the call to .format
, or try expanding the tuple yourself, or try using named parameter access in the .format
call:
ball100 = ball(100)
"py ball: {}, u ball: {}".format(*ball100) # splat! Flatten the tuple
"py ball: {}, u ball: {}".format(ball100[0], ball100[1]) # DIY
"py ball: {ball[0]}, u ball: {ball[1]}".format(ball=ball100) # named arg
Upvotes: 0
Reputation: 12927
Your format string requires two arguments to .format
, but you provide only one (which is a two-element tuple, but it is still one argument).
On the other hand, %
operator requires a single tuple as its right-hand argument, so it is OK. You could unpack your tuple using prefix asterisk operator:
b = ball(100)
print("py ball: {}, u ball: {}".format(*b))
Upvotes: 0