146

I construct a string s in Python 2.6.5 which will have a varying number of %s tokens, which match the number of entries in list x. I need to write out a formatted string. The following doesn't work, but indicates what I'm trying to do. In this example, there are three %s tokens and the list has three entries.

s = '%s BLAH %s FOO %s BAR'
x = ['1', '2', '3']
print s % (x)

I'd like the output string to be:

1 BLAH 2 FOO 3 BAR

1

8 Answers 8

195

You should take a look to the format method of python. You could then define your formatting string like this :

>>> s = '{0} BLAH BLAH {1} BLAH {2} BLAH BLIH BLEH'
>>> x = ['1', '2', '3']
>>> print s.format(*x)
'1 BLAH BLAH 2 BLAH 3 BLAH BLIH BLEH'
Sign up to request clarification or add additional context in comments.

8 Comments

The OP's problem is not the method but the format of the parameters. % operator only unpacks tuples.
@SabreWolfy If you construct it precedurally then you might find it easier to name your placeholders and use a dict to format the resulting string: print u'%(blah)d BLAHS %(foo)d FOOS …' % {'blah': 15, 'foo': 4}.
@SabreWolfy: In Python 2.7, you can omit the field numbers: s = '{} BLAH {} BLAH BLAH {} BLAH BLAH BLAH'
What is the meaning, or function, of the asterisk (*) ?
@kotchwane : the * function is a special python keyword that transform an argument that is a list into a list of arguements :). In our case, *x will pass to the format method the 3 members of x.
|
130
print s % tuple(x)

instead of

print s % (x)

7 Comments

(x) is the same thing as x. Putting a single token in brackets has no meaning in Python. You usually put brackets in foo = (bar, ) to make it easier to read but foo = bar, does exactly the same thing.
print s % (x) is what OP wrote, I was just quoting him/her.
I was just providing a language tip, not criticizing your answer (in fact I +1'd it). You did not write foo = (bar, ) either :)
I use the (x) notation for clarity; it also avoids forgetting the brackets if you later add additional variables.
This is the best answer! It's much simpler and shorter than the .format() one, which is undeservedly the most upvoted one!!
|
45

Following this resource page, if the length of x is varying, we can use:

', '.join(['%.2f']*len(x))

to create a place holder for each element from the list x. Here is the example:

x = [1/3.0, 1/6.0, 0.678]
s = ("elements in the list are ["+', '.join(['%.2f']*len(x))+"]") % tuple(x)
print s
>>> elements in the list are [0.33, 0.17, 0.68]

Comments

31

Here is a one liner. A little improvised answer using format with print() to iterate a list.

How about this (python 3.x):

sample_list = ['cat', 'dog', 'bunny', 'pig']
print("Your list of animals are: {}, {}, {} and {}".format(*sample_list))

Read the docs here on using format().

2 Comments

What is the meaning, or function, of the asterisk (*) ? Your link to the documentation does not seem to clarify that.
@kotchwane the asterisk "expands" the list as individual ordered arguments. f(*x) == f(x[0], x[1], ..., x[n]). Similarly, two asterisks (**) expands a dict to keyword arguments.
22

Since I just learned about this cool thing(indexing into lists from within a format string) I'm adding to this old question.

s = '{x[0]} BLAH {x[1]} FOO {x[2]} BAR'
x = ['1', '2', '3']
print (s.format (x=x))

Output:

1 BLAH 2 FOO 3 BAR

However, I still haven't figured out how to do slicing(inside of the format string '"{x[2:4]}".format...,) and would love to figure it out if anyone has an idea, however I suspect that you simply cannot do that.

3 Comments

I am a little curious about your use case for slicing.
i dont really have one ... i think i just thought it would be neat to be able to do
Note that you can also do: '{0[0]} BLAH {0[1]} FOO {0[2]} BAR'.format(x). In other words, you do not need to name the argument.
12

This was a fun question! Another way to handle this for variable length lists is to build a function that takes full advantage of the .format method and list unpacking. In the following example I don't use any fancy formatting, but that can easily be changed to suit your needs.

list_1 = [1,2,3,4,5,6]
list_2 = [1,2,3,4,5,6,7,8]

# Create a function that can apply formatting to lists of any length:
def ListToFormattedString(alist):
    # Create a format spec for each item in the input `alist`.
    # E.g., each item will be right-adjusted, field width=3.
    format_list = ['{:>3}' for item in alist] 

    # Now join the format specs into a single string:
    # E.g., '{:>3}, {:>3}, {:>3}' if the input list has 3 items.
    s = ','.join(format_list)

    # Now unpack the input list `alist` into the format string. Done!
    return s.format(*alist)

# Example output:
>>>ListToFormattedString(list_1)
'  1,  2,  3,  4,  5,  6'
>>>ListToFormattedString(list_2)
'  1,  2,  3,  4,  5,  6,  7,  8'

Comments

7

For just filling in an arbitrary list of values to a string, you could do the following, which is the same as @neobot's answer but a little more modern and succinct.

>>> l = range(5)
>>> " & ".join(["{}"]*len(l)).format(*l)
'0 & 1 & 2 & 3 & 4'

If what you are concatenating together is already some kind of structured data, I think it would be better to do something more like:

>>> data = {"blah": 1, "foo": 2, "bar": 3}
>>> " ".join([f"{k} {v}" for k, v in data.items()])
'blah 1 foo 2 bar 3'

Comments

1
x = ['1', '2', '3']
s = f"{x[0]} BLAH {x[1]} FOO {x[2]} BAR"
print(s)

The output is

1 BLAH 2 FOO 3 BAR

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.