Strings & String Formatting Interview Questions & Answers

6 questions Updated 2026-06-18

Python interview questions on f-strings vs .format vs %, str vs bytes, common string methods, join vs +=, raw strings, and the format spec mini-language.

All three interpolate values into strings. % is the oldest C-style syntax. str.format() uses {} placeholders and is more flexible. f-strings (Python 3.6+) embed expressions inline and are the fastest and most readable.

name, n = "Ada", 3
"Hi %s, %d items" % (name, n)        # old % style
"Hi {}, {} items".format(name, n)    # str.format
f"Hi {name}, {n} items"              # f-string — preferred
f"{n * 2 = }"                        # "n * 2 = 6"  — self-documenting

Rule of thumb: prefer f-strings for new code — they evaluate expressions directly and avoid the argument-ordering errors of % and .format().

A str is a sequence of Unicode code points (text); bytes is a sequence of raw bytes (0-255). You convert between them with encode (str -> bytes) and decode (bytes -> str), specifying an encoding like UTF-8.

s = "café"
b = s.encode("utf-8")    # b'caf\xc3\xa9'  — 5 bytes (é is 2)
b.decode("utf-8")        # "café"  — back to text
len(s), len(b)           # (4, 5)
s + b                    # TypeError — can't mix str and bytes

Why it matters: files and network sockets deal in bytes, your program logic in str. Rule of thumb: decode bytes to str as early as possible and encode back to bytes only at the I/O boundary.

split breaks a string into a list on a separator; strip removes leading/trailing whitespace (or given characters); join glues an iterable of strings together with a separator. All return new strings since str is immutable.

"  a,b,c  ".strip()            # "a,b,c"
"a,b,c".split(",")            # ["a", "b", "c"]
",".join(["a", "b", "c"])     # "a,b,c"
"Hello".lower(), "Hi".upper() # ("hello", "HI")
"hello".replace("l", "L")     # "heLLo"

Rule of thumb: sep.join(list) is the inverse of text.split(sep), and chaining these covers most everyday text wrangling.

Strings are immutable, so each += creates a brand-new string and copies everything so far — turning a loop into O(n^2) work and lots of garbage. join allocates the result once, making it O(n).

# Slow — new string every iteration
result = ""
for word in words:
    result += word

# Fast — single allocation
result = "".join(words)

Rule of thumb: collect pieces in a list (or generator) and call "".join(...) — it's the Python equivalent of a StringBuilder.

A raw string (r"...") tells Python not to process backslash escapes, so \n, \t, etc. stay as literal backslash-plus-character. They're ideal for regular expressions and Windows file paths.

print("a\tb")    # a    b   — \t is a tab
print(r"a\tb")   # a\tb     — backslash kept literally

import re
re.findall(r"\d+", "x12y3")   # ['12', '3']  — no double-backslashing
path = r"C:\Users\name"       # backslashes stay intact

Rule of thumb: reach for r"..." whenever your string is full of backslashes — it avoids the noise and bugs of escaping every one.

Inside {} (or after : in format), a format spec controls alignment, width, and precision: {value:[fill][align][width][,][.precision][type]}. It works in f-strings and str.format alike.

f"{42:5}"        # "   42"    — width 5, right-aligned (default for numbers)
f"{'hi':<5}|"    # "hi   |"   — left-align in width 5
f"{'hi':^5}|"    # " hi  |"   — center
f"{42:05}"       # "00042"    — zero-padded
f"{3.14159:.2f}" # "3.14"     — 2 decimal places
f"{1234567:,}"   # "1,234,567"  — thousands separator
f"{0.25:.1%}"    # "25.0%"    — percentage

Rule of thumb: .2f controls decimals, a number sets width, and </>/^ set alignment — combine them for clean tabular output.

Practice tests are coming soon

Get notified when interactive mock interviews and quizzes launch.