python
ruby
string-interpolation
programming-languages
code-comparison

Is there a Python equivalent to Ruby's string interpolation?

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Introduction

Ruby's #{} string interpolation has a direct equivalent in Python: f-strings (formatted string literals), available since Python 3.6. Before f-strings, Python offered str.format() and % formatting. All three approaches embed variables and expressions inside strings, but f-strings are the closest match to Ruby's syntax in terms of readability and conciseness.

Ruby String Interpolation

ruby
1name = "Alice"
2age = 30
3puts "Hello, #{name}! You are #{age} years old."
4# Hello, Alice! You are 30 years old.
5
6# Expressions inside interpolation
7puts "In 5 years you'll be #{age + 5}."
8# In 5 years you'll be 35.
9
10# Method calls
11puts "Name uppercase: #{name.upcase}"
12# Name uppercase: ALICE

Ruby's #{} only works inside double-quoted strings ("..."). Single-quoted strings ('...') treat #{} as literal text.

Python f-strings (Best Equivalent)

python
1name = "Alice"
2age = 30
3print(f"Hello, {name}! You are {age} years old.")
4# Hello, Alice! You are 30 years old.
5
6# Expressions
7print(f"In 5 years you'll be {age + 5}.")
8# In 5 years you'll be 35.
9
10# Method calls
11print(f"Name uppercase: {name.upper()}")
12# Name uppercase: ALICE

F-strings are prefixed with f or F and use {} for interpolation. Any valid Python expression works inside the braces.

f-string Features

python
1import math
2
3# Format specifiers
4pi = 3.14159265
5print(f"Pi: {pi:.2f}")          # Pi: 3.14
6print(f"Pi: {pi:10.4f}")        # Pi:     3.1416
7
8# Alignment and padding
9name = "Bob"
10print(f"|{name:<10}|")          # |Bob       |
11print(f"|{name:>10}|")          # |       Bob|
12print(f"|{name:^10}|")          # |   Bob    |
13
14# Numbers
15n = 1000000
16print(f"{n:,}")                  # 1,000,000
17print(f"{n:_}")                  # 1_000_000
18
19# Hex, oct, bin
20x = 255
21print(f"{x:#x}")                 # 0xff
22print(f"{x:#o}")                 # 0o377
23print(f"{x:#b}")                 # 0b11111111
24
25# Debug format (Python 3.8+)
26value = 42
27print(f"{value = }")             # value = 42
28print(f"{2 + 2 = }")            # 2 + 2 = 4
29
30# Multiline f-strings
31data = {"name": "Alice", "score": 95}
32message = (
33    f"Student: {data['name']}\n"
34    f"Score: {data['score']}/100\n"
35    f"Grade: {'A' if data['score'] >= 90 else 'B'}"
36)
37print(message)

str.format() (Python 2.6+)

python
1name = "Alice"
2age = 30
3
4# Positional arguments
5print("Hello, {}! You are {} years old.".format(name, age))
6
7# Named arguments
8print("Hello, {name}! Age: {age}".format(name=name, age=age))
9
10# Index-based
11print("{0} is {1}. {0} says hi.".format(name, age))
12
13# Format specifiers
14print("Pi: {:.2f}".format(3.14159))  # Pi: 3.14
15
16# Dictionary unpacking
17data = {"name": "Bob", "age": 25}
18print("Hello, {name}! Age: {age}".format(**data))

% Formatting (Old Style)

python
1name = "Alice"
2age = 30
3
4print("Hello, %s! You are %d years old." % (name, age))
5# Hello, Alice! You are 30 years old.
6
7print("Pi: %.2f" % 3.14159)  # Pi: 3.14
8
9# Named substitution with dict
10print("%(name)s is %(age)d" % {"name": name, "age": age})

% formatting is the oldest approach and still works, but f-strings and str.format() are preferred for new code.

Template Strings (Safe User Input)

python
1from string import Template
2
3name = "Alice"
4t = Template("Hello, $name!")
5print(t.substitute(name=name))  # Hello, Alice!
6
7# Safe substitute — ignores missing variables
8t = Template("Hello, $name! Your $role.")
9print(t.safe_substitute(name=name))  # Hello, Alice! Your $role.

Template is useful when the format string comes from user input because it does not allow arbitrary expression evaluation (unlike f-strings).

Comparison

FeatureRuby #{}Python f-stringstr.format()% formatting
Syntax"#{expr}"f"{expr}""{}.format()""%s" % val
ExpressionsYesYesLimitedNo
Min Python versionN/A3.62.6All
PerformanceFastFastestSlowerModerate
Format specsRuby methods{val:.2f}{:.2f}%.2f

Common Pitfalls

  • Using f-strings with untrusted input: f-strings evaluate arbitrary Python expressions. Never use eval(f"...") or construct f-strings from user-provided templates — this is a code injection risk. Use Template for user-supplied format strings.
  • Forgetting the f prefix: "{name}" is a plain string containing the literal text {name}. Only f"{name}" interpolates the variable. This is a common mistake when copying code.
  • Backslashes inside f-string braces: Backslashes are not allowed inside {} in f-strings. Use a variable: newline = '\n'; f"line1{newline}line2" instead of f"line1{'\n'}line2".
  • Single vs double quotes in Ruby: Ruby only interpolates inside double-quoted strings. 'Hello #{name}' prints the literal #{name}. Python f-strings work with both single and double quotes.
  • Performance of str.format() in loops: In tight loops, f-strings are measurably faster than str.format() because they are compiled at parse time rather than being method calls at runtime.

Summary

  • Python f-strings (f"{var}") are the direct equivalent of Ruby's #{} interpolation
  • f-strings support expressions, method calls, format specifiers, and debug output (=)
  • str.format() and % formatting are older alternatives still used in Python 2 codebases
  • Use Template strings for user-provided format strings to prevent code injection
  • f-strings are the fastest string formatting method in Python
  • Always include the f prefix — "{var}" without f is a plain string literal

Related reading
Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.