2

How can I use functions that return multiple values as inputs to a format string, without getting the TypeError: not enough arguments for format string error?

>>> def foo():
...     return 1, 2
... 
>>> foo()
(1, 2)
>>> print "%d,%d,%d" % foo(), 3
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: not enough arguments for format string

Expected output: "1,2,3"

1
  • 1
    print "%d,%d,%d" % (foo() + (3,)) should do it. Commented Feb 10, 2015 at 1:00

3 Answers 3

3

Element index

string.format() is more powerful and lets you access list elements or even attributes:

>>> print "{0[0]},{0[1]},{1}".format(foo(), 3)
1,2,3

Concatenate tuple

The problem with foo(), 3 is that it's a tuple and an integer, two different types. Instead you can create a 3-tuple via concatenation. If you use string.format() it's a bit trickier, as you need to unpack it first using the * operator so you can use it as arguments:

>>> foo() + (3,)
(1, 2, 3)

>>> print "%d,%d,%d" % (foo() + (3,))
1,2,3

>>> print "{},{},{}".format(*foo() + (3,))
1,2,3

Temporary variables

Of course, you can always do it this way, which is obvious but verbose:

>>> foo1, foo2 = foo()
>>> print "%d,%d,%d" % (foo1, foo2, 3)
1,2,3
Sign up to request clarification or add additional context in comments.

1 Comment

Ouch! I didn't reallize you already had (foo() + (3,)) in your answer. :/
2

The reason print "%d,%d,%d" % foo(), 3 is not working is because Python is thinking you're trying to print two items here: "%d,%d,%d" % foo() and then 3. Due to this the first expression clearly fails because of in-sufficient number of items:

>>> def func():
...     print "%d,%d,%d" % foo(), 3
...     
>>> import dis
>>> dis.dis(func)
  2           0 LOAD_CONST               1 ('%d,%d,%d')
              3 LOAD_GLOBAL              0 (foo)
              6 CALL_FUNCTION            0
              9 BINARY_MODULO       
             10 PRINT_ITEM          
             11 LOAD_CONST               2 (3)
             14 PRINT_ITEM          
             15 PRINT_NEWLINE       
             16 LOAD_CONST               0 (None)
             19 RETURN_VALUE        

In fact even something like "%d,%d,%d" % foo() + (3,) won't work because I guess operator precedence comes into play here:

>>> def func():
    print "%d,%d,%d" % foo() + (3,)
...     
>>> dis.dis(func)
  2           0 LOAD_CONST               1 ('%d,%d,%d')
              3 LOAD_GLOBAL              0 (foo)
              6 CALL_FUNCTION            0
              9 BINARY_MODULO       
             10 LOAD_CONST               3 ((3,))
             13 BINARY_ADD          
             14 PRINT_ITEM          
             15 PRINT_NEWLINE       
             16 LOAD_CONST               0 (None)
             19 RETURN_VALUE 

A working version will be:

>>> print "%d,%d,%d" % (foo() + (3,))
1,2,3

Comments

0

A general solution to take an arbitrary number of arguments and print them with some delimiter would be to use str.join

def foo():
    return 1, 2

>>> print(','.join(map(str,foo())))
1,2

Another example

def bar():
    return 4,5,6,7

>>> print(','.join(map(str,bar())))
4,5,6,7

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.