Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does assignment of split to print formatting not work?

I am puzzled why I can assign/unpack the return of split() to the appropriate number of variables, but the same fails for use in a print string using formatting directives.

E.g., given:

In [202]: s
Out[202]: 'here are 4 values'

In [203]: s.split()
Out[203]: ['here', 'are', '4', 'values']

This works as expected:

In [204]: a, b, c, d = s.split()

In [205]: print '%s %s %s %s' % (a, b, c, d)
here are 4 values

But this fails ..

 In [206]: print '%s %s %s %s' % (s.split())

I am not sure why? Shouldn't the return of split() be unpacked and be distributed over the expected arguments for the formatting strings?

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
C:\bla\Desktop\<ipython-input-206-600f130ff0b2> in <module>()
----> 1 print '%s %s %s %s' % (s.split())

TypeError: not enough arguments for format string

"Note enough arguments" .. I do have the right number of items in the list. Does the list for some reason not unpack in this case, but does with assignments to variables?

I came across this in attempting to answer this question writing column entry just one below another in python

like image 650
Levon Avatar asked Dec 17 '22 00:12

Levon


2 Answers

You must convert s.split() into a tuple like so

>>> s = 'here are 4 values'
>>> '%s %s %s %s' % tuple(s.split())
'here are 4 values'

for formatting or use .format() instead, unpacking the arguments.

'{0} {1} {2} {3}'.format(*s.split())
like image 144
jamylak Avatar answered Mar 06 '23 17:03

jamylak


The fundamental problem is that %-formatting and unpacking aren't related at all. The % requires that the values be in a tuple; other kinds of sequences won't work. (It will accept a single non-tuple value though.)

This has the unfortunate consequence that all tuples are interpreted as tuples of values, whether or not that's desirable. So to treat a tuple as a value, you have to encase it in another tuple:

>>> '%s' % ('a', 'b')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: not all arguments converted during string formatting
>>> '%s' % (('a', 'b'),)
"('a', 'b')"

Using format is preferable anyway.

like image 31
senderle Avatar answered Mar 06 '23 16:03

senderle