365

Ruby example:

name = "Spongebob Squarepants"
puts "Who lives in a Pineapple under the sea? \n#{name}."

The successful Python string concatenation is seemingly verbose to me.

5
  • 2
    The issue here is that name is a local variable lying in the string, and in Python you have to explicitly pass the dictionary of local variables to the string formatter if you want it to use them. Commented Dec 15, 2010 at 14:58
  • This wasn't the original issue, but thanks. Your comment gave me a little better understanding of variable scope (something I'm still gaining ground with). :) Commented Dec 15, 2010 at 15:00
  • 1
    What do you think about this one, then? stackoverflow.com/questions/16504732/… Commented May 12, 2013 at 12:32
  • PEP 215 -- String Interpolation - superseded by python.org/dev/peps/pep-0292 Commented Oct 4, 2015 at 14:33
  • 2
    See stackoverflow.com/a/33264516/55721 for this exact feature in 3.6 Commented Jul 20, 2016 at 16:17

9 Answers 9

437

Python 3.6 will add literal string interpolation similar to Ruby's string interpolation. Starting with that version of Python (which is scheduled to be released by the end of 2016), you will be able to include expressions in "f-strings", e.g.

name = "Spongebob Squarepants"
print(f"Who lives in a Pineapple under the sea? {name}.")

Prior to 3.6, the closest you can get to this is

name = "Spongebob Squarepants"
print("Who lives in a Pineapple under the sea? %(name)s." % locals())

The % operator can be used for string interpolation in Python. The first operand is the string to be interpolated, the second can have different types including a "mapping", mapping field names to the values to be interpolated. Here I used the dictionary of local variables locals() to map the field name name to its value as a local variable.

The same code using the .format() method of recent Python versions would look like this:

name = "Spongebob Squarepants"
print("Who lives in a Pineapple under the sea? {name!s}.".format(**locals()))

There is also the string.Template class:

tmpl = string.Template("Who lives in a Pineapple under the sea? $name.")
print(tmpl.substitute(name="Spongebob Squarepants"))
Sign up to request clarification or add additional context in comments.

8 Comments

@Caste see here: docs.python.org/library/stdtypes.html#string-formatting and post a follow up comment if you need any more details
I understand the basic gist of it, I don't fully understand all the additional symbols and text found in the example in the documentation however. Why the use of convert to string here: %(language)s What does the 3 in '03d' signify? Why after the string is there % \? The assignment of variables (if they are in fact variables) after the print expression confuses me also. Sorry if this is a pain!
The two basic formats used in the example are %s for a string and %03d for a number padded to 3 digits with leading zeroes. It could just be written print "%s has %03d" % ("Python", 2). The example then makes use of putting a mapping key in brackets after the % which is a way of giving the placeholders meaningful names rather than relying on their order in the string. You then pass a dictionary that maps the key names to their values. That's why Sven is using the locals() function which returns a dict containing all your local variables so it will map name to the value of name
The required usage of a conversion type was what first confused me. So, using the documentation terminology. The % starts the specifier. There is no conversion flag for (language), just a conversion type (the trailing 's'); (number) however has one (or two) conversion flags which is '0' (and '3' respectively). The 'd' is the conversion type and signifies it is an integer. Did I understand correctly?
@Caste: Yes, that's basically right. Note that you could always use a s as a conversion type -- Python can convert just about anything to a string. But of course you would lose the special formatting capabilities of other conversion types.
|
152

Since Python 2.6.X you might want to use:

"my {0} string: {1}".format("cool", "Hello there!")

3 Comments

Note that the % operator for string interpolation is not deprecated in Python 3.x. docs.python.org/dev/py3k/whatsnew/… announces the plan to deprecate % starting in 3.1, but this never happened.
%-syntax still lives on in Python 3 (not deprecated as of Python 3.2)
Just a note: the number in {} can me eliminated.
32

I've developed the interpy package, that enables string interpolation in Python.

Just install it via pip install interpy. And then, add the line # coding: interpy at the beginning of your files!

Example:

#!/usr/bin/env python
# coding: interpy

name = "Spongebob Squarepants"
print "Who lives in a Pineapple under the sea? \n#{name}."

2 Comments

This seems really insecure.
@d33tah: No, as long as the strings are known at compile time.
29

Python's string interpolation is similar to C's printf()

If you try:

name = "SpongeBob Squarepants"
print "Who lives in a Pineapple under the sea? %s" % name

The tag %s will be replaced with the name variable. You should take a look to the print function tags: http://docs.python.org/library/functions.html

2 Comments

how i can do this way with 2 variables?
@JulioMarins Use a tuple: print "First is %s, second is %s" % (var1, var2).
28

String interpolation is going to be included with Python 3.6 as specified in PEP 498. You will be able to do this:

name = 'Spongebob Squarepants'
print(f'Who lives in a Pineapple under the sea? \n{name}')

Note that I hate Spongebob, so writing this was slightly painful. :)

1 Comment

Thx for that Spongebob reference (/distaste): gotta upvote this now.
4

You can also have this

name = "Spongebob Squarepants"
print "Who lives in a Pineapple under the sea? \n{name}.".format(name=name)

http://docs.python.org/2/library/string.html#formatstrings

2 Comments

I don't believe OP intended the # to be printed. They are just using Ruby syntax.
You're right. I edited the answer. I am not familiar with Ruby, so I thought the # character would be printed.
3
import inspect
def s(template, **kwargs):
    "Usage: s(string, **locals())"
    if not kwargs:
        frame = inspect.currentframe()
        try:
            kwargs = frame.f_back.f_locals
        finally:
            del frame
        if not kwargs:
            kwargs = globals()
    return template.format(**kwargs)

Usage:

a = 123
s('{a}', locals()) # print '123'
s('{a}') # it is equal to the above statement: print '123'
s('{b}') # raise an KeyError: b variable not found

PS: performance may be a problem. This is useful for local scripts, not for production logs.

Duplicated:

Comments

3

Python 3.6 and newer have literal string interpolation using f-strings:

name='world'
print(f"Hello {name}!")

Comments

2

For old Python (tested on 2.4) the top solution points the way. You can do this:

import string

def try_interp():
    d = 1
    f = 1.1
    s = "s"
    print string.Template("d: $d f: $f s: $s").substitute(**locals())

try_interp()

And you get

d: 1 f: 1.1 s: s

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.