Python Strings: Slicing, Indexing, f-Strings, String Methods, Encoding, Escape Characters, Multiline Strings, and Why Strings Are Immutable
Strings are everywhere in data engineering — column names, file paths, SQL queries, API responses, log messages, error messages. You will work with strings more than any other data type. Yet most tutorials cover strings in 5 minutes: “use quotes, call .upper(), done.” That is not enough.
This post covers strings from the ground up — how Python stores them in memory (they are immutable sequences of Unicode characters), every way to create and format them, slicing with the three-parameter syntax, all the methods you will actually use in production, and the encoding concepts that matter when reading files from different systems.
Think of a string like a necklace of beads. Each bead is a character. The necklace has a fixed order — you can look at bead #3 (indexing), take a section of beads #2 through #5 (slicing), or create an entirely new necklace by rearranging beads (concatenation). But you cannot change a bead on the existing necklace — if you want a different color at position #3, you make a new necklace (immutability).
Table of Contents
- Creating Strings
- Single, Double, and Triple Quotes
- Raw Strings
- Strings in Memory: Immutability
- Why Immutability Matters
- Indexing
- Positive and Negative Indexing
- IndexError and Safe Access
- Slicing
- Basic Slicing [start:stop]
- Slicing with Step [start:stop:step]
- Common Slicing Patterns
- Escape Characters
- String Formatting
- f-Strings (Recommended)
- f-String Advanced Features
- .format() Method
- % Formatting (Legacy)
- String Methods — Searching
- find() and index()
- count()
- startswith() and endswith()
- in Operator
- String Methods — Modifying (Returns New String)
- upper(), lower(), title(), capitalize(), swapcase()
- strip(), lstrip(), rstrip()
- replace()
- center(), ljust(), rjust(), zfill()
- String Methods — Splitting and Joining
- split() and rsplit()
- splitlines()
- join()
- partition() and rpartition()
- String Methods — Checking
- isdigit(), isnumeric(), isdecimal()
- isalpha(), isalnum(), isspace()
- isupper(), islower(), istitle()
- String Concatenation and Repetition
- Performance: Why + in a Loop Is Bad
- Strings and Unicode (Encoding)
- UTF-8 and Why It Matters for Data Engineers
- encode() and decode()
- Strings in Data Engineering
- Building SQL Queries
- Parsing File Paths
- Cleaning Data Strings
- Common Mistakes
- Interview Questions
- Wrapping Up
Creating Strings
Single, Double, and Triple Quotes
# Single and double quotes — identical behavior
name = 'Naveen'
name = "Naveen" # No difference — pick one style and be consistent
# Use the OTHER quote when your string CONTAINS quotes
message = "It's a beautiful day" # Single quote inside double quotes
html = '<div class="header">Hello</div>' # Double quotes inside single quotes
# Triple quotes — multiline strings
bio = """Naveen Vuppula is a
Senior Data Engineering Consultant
based in Ontario, Canada."""
# Triple quotes preserve newlines and indentation exactly as written
sql = """
SELECT customer_id, first_name, last_name
FROM silver.customers
WHERE city = 'Toronto'
ORDER BY last_name
"""
print(sql) # Prints with all newlines and indentation
# Triple quotes are also used for docstrings (function documentation)
def process_data(df):
"""
Clean and transform the input DataFrame.
Args:
df: Raw PySpark DataFrame from Bronze layer
Returns:
Cleaned DataFrame ready for Silver layer
"""
pass
Raw Strings
# Raw strings (prefix with r) treat backslashes as literal characters
# Essential for: file paths (Windows), regex patterns
# WITHOUT raw string — backslash is an escape character
path = "C:
ew_folder est"
print(path) # C:
# ew_folder est ←
and are interpreted as newline and tab!
# WITH raw string — backslashes are literal
path = r"C:
ew_folder est"
print(path) # C:
ew_folder est ← Correct!
# Regex patterns should ALWAYS use raw strings
import re
pattern = r"\d{3}-\d{3}-\d{4}" # Matches: 416-555-1234
# Without r: "\d{3}-\d{3}-\d{4}" — messy double backslashes
Strings in Memory: Immutability
Why Immutability Matters
# Strings are IMMUTABLE — you cannot change characters in place
name = "Naveen"
# name[0] = "D" # TypeError: 'str' object does not support item assignment
# Every "modification" creates a NEW string object
name = "naveen"
print(id(name)) # address A
upper_name = name.upper()
print(id(upper_name)) # address B — different object!
print(name) # "naveen" — original is UNCHANGED
# Even += creates a new string
greeting = "Hello"
print(id(greeting)) # address A
greeting += " World"
print(id(greeting)) # address B — new string, new object
# Why immutable?
# 1. SAFETY: strings used as dict keys must not change
# 2. MEMORY: Python can intern (reuse) identical strings
# 3. THREADING: immutable objects are thread-safe (no locks needed)
# 4. HASHING: immutable objects can be hashed (needed for dict keys and sets)
Real-life analogy: A string is like a printed page. You cannot erase and rewrite one word on the page. To “change” it, you print a new page with the correction. The original page still exists unchanged until nobody needs it anymore (garbage collection).
Indexing
Positive and Negative Indexing
String: P y t h o n
Positive: 0 1 2 3 4 5
Negative: -6 -5 -4 -3 -2 -1
Positive index: counts from the LEFT, starting at 0
Negative index: counts from the RIGHT, starting at -1
text = "Python"
print(text[0]) # 'P' — first character
print(text[5]) # 'n' — last character (index 5)
print(text[-1]) # 'n' — last character (negative index)
print(text[-2]) # 'o' — second to last
print(text[-6]) # 'P' — first character via negative index
# Practical use: get file extension
filename = "sales_data_2026.csv"
print(filename[-3:]) # "csv" — last 3 characters
IndexError and Safe Access
text = "Python"
# print(text[10]) # IndexError: string index out of range
# Safe access patterns:
# 1. Check length first
if len(text) > 10:
print(text[10])
# 2. Use try/except
try:
char = text[10]
except IndexError:
char = "" # Default empty string
# 3. Use slicing (never raises IndexError!)
print(text[10:11]) # "" — empty string, no error
# Slicing is forgiving — out-of-range indices return empty, not errors
Slicing
Basic Slicing [start:stop]
text = "Python Programming"
# [start:stop] — includes start, EXCLUDES stop
print(text[0:6]) # "Python" (chars at index 0,1,2,3,4,5)
print(text[7:18]) # "Programming"
print(text[7:]) # "Programming" (omit stop = go to end)
print(text[:6]) # "Python" (omit start = start from 0)
print(text[:]) # "Python Programming" (copy entire string)
# Think of indices as BETWEEN characters:
# | P | y | t | h | o | n | | P | r | o | ...
# 0 1 2 3 4 5 6 7 8 9 10
# text[0:6] = everything between position 0 and position 6
Slicing with Step [start:stop:step]
text = "Python Programming"
# [start:stop:step] — take every Nth character
print(text[0:6:2]) # "Pto" (every 2nd char: P, t, o)
print(text[::2]) # "Pto rgamn" (every 2nd char, full string)
print(text[::3]) # "Ph rmig" (every 3rd char)
# Negative step — goes RIGHT to LEFT
print(text[::-1]) # "gnimmargorP nohtyP" (reversed string!)
print(text[::-2]) # "gimroP oty" (every 2nd char, reversed)
print(text[5::-1]) # "nohtyP" (from index 5, go backwards to start)
# Common patterns:
text = "Hello World"
print(text[::-1]) # "dlroW olleH" (reverse)
print(text[:5]) # "Hello" (first 5 chars)
print(text[-5:]) # "World" (last 5 chars)
print(text[::2]) # "HloWrd" (every other char)
Common Slicing Patterns
# Data engineering slicing patterns
filename = "sales_report_2026_Q2.csv"
print(filename[-4:]) # ".csv" — file extension
print(filename[:-4]) # "sales_report_2026_Q2" — name without extension
print(filename.split("_")[-1].split(".")[0]) # "Q2" — extract quarter
# Extract parts of a date string
date_str = "2026-06-15"
year = date_str[:4] # "2026"
month = date_str[5:7] # "06"
day = date_str[8:10] # "15"
# Check palindrome
word = "racecar"
print(word == word[::-1]) # True — it is a palindrome
Escape Characters
| Escape | Meaning | Example | Output |
|---|---|---|---|
| Newline | "Line1
Line2" | Line1 Line2 |
| Tab | "Col1 Col2" | Col1 Col2 |
\ | Literal backslash | "C:\folder" | C:older |
' | Single quote | 'It's here' | It’s here |
" | Double quote | "She said "hi"" | She said “hi” |
| Carriage return | "Hello
World" | World (overwrites) |
|