Programmer's Picnic · Python Foundations · 0 → ∞

Python Strings: From 0 to Infinity

Start with a word. Finish by building a safe, useful text-processing toolkit.

Free course · 55–75 minutes reading and practice · No installation beyond Python 3

How to learn

Read one level, type the code into the editor, predict the output, then run it. Change one line and observe the result before proceeding. All code examples work with standard Python 3 (the dictionary union example requires 3.9 or newer).

The course moves from first principles to realistic code, common mistakes, performance and a mini-project.

Level 0 / 10

0 · What is a string?

A string is an ordered sequence of Unicode characters. Surround text with single or double quotes; triple quotes are useful for multi-line text.

Python 3 · runnable example
name = 'Asha'
city = "Varanasi"
message = '''Python is fun.
Keep practising!'''
print(name, city)
print(type(name).__name__)
Expected output
Asha Varanasi
str

Remember: Numbers inside quotation marks are text. "12" + "3" is "123", while 12 + 3 is 15.

Level 1 / 10

1 · Indexing and length

Positions start at zero. Negative indices count backwards. Use len() to count Unicode code points (not necessarily visible characters).

Python 3 · runnable example
word = 'PYTHON'
print(word[0], word[-1])
print(len(word))
print('y' in word.lower())
Expected output
P N
6
True

Remember: An out-of-range index raises IndexError. Use len() to check before indexing.

Level 2 / 10

2 · Slicing text

The slice pattern [start:stop:step] includes start and excludes stop. Missing values mean use the beginning, end or step 1.

Python 3 · runnable example
s = 'Programming'
print(s[0:7])
print(s[-4:])
print(s[::2])
print(s[::-1])
Expected output
Program
ming
Pormig
gnimmargorP

Remember: Slicing beyond the string length is safe; indexing beyond it is not.

Level 3 / 10

3 · Why strings are immutable

You cannot replace one character inside an existing string. Build a new string using slicing, replace() or concatenation.

Python 3 · runnable example
word = 'cat'
new_word = 'b' + word[1:]
print(word)
print(new_word)
print(word.replace('a', 'u'))
Expected output
cat
bat
cut

Remember: word[0] = 'b' raises TypeError. Methods such as upper() return new strings.

Level 4 / 10

4 · Clean and search

Use strip() to remove surrounding whitespace, lower() or casefold() for caseless matching, find() for index and count() for occurrences.

Python 3 · runnable example
raw = '  BANANA  '
text = raw.strip().casefold()
print(text)
print(text.find('na'))
print(text.count('na'))
print(text.startswith('ba'))
Expected output
banana
2
2
True

Remember: find() returns -1 when a substring is missing. index() raises ValueError instead.

Level 5 / 10

5 · Split and join

split() turns text into a list. join() joins an iterable of strings using a separator; it is the preferred way to assemble many pieces.

Python 3 · runnable example
line = 'red,green,blue'
colours = line.split(',')
print(colours)
print(' | '.join(colours))
print('-'.join(['2026', '10', '17']))
Expected output
['red', 'green', 'blue']
red | green | blue
2026-10-17

Remember: join() requires strings. Convert numbers using str() if necessary.

Level 6 / 10

6 · Format readable output

f-strings evaluate expressions within braces and support precision, alignment and grouping. Avoid building SQL queries from user input; use SQL parameters instead.

Python 3 · runnable example
name = 'Meera'
marks = 87.456
price = 12345.5
print(f'{name}: {marks:.1f}%')
print(f'₹{price:,.2f}')
print(f'{name:>10}')
Expected output
Meera: 87.5%
₹12,345.50
     Meera

Remember: Formatting affects the display, not the underlying numeric value.

Level 7 / 10

7 · Unicode and UTF-8

Python strings hold Unicode text. encode() produces bytes; decode() converts bytes back to text. Open text files with an explicit UTF-8 encoding for portability.

Python 3 · runnable example
greeting = 'नमस्ते Python'
encoded = greeting.encode('utf-8')
print(type(encoded).__name__)
print(encoded.decode('utf-8') == greeting)
print('न' in greeting)
Expected output
bytes
True
True

Remember: len() counts code points, not always what readers perceive as individual characters.

Level 8 / 10

8 · Regular expressions

Regular expressions are helpful for controlled patterns. Fullmatch checks the whole input. Use raw r'...' patterns so backslashes behave as intended.

Python 3 · runnable example
import re
pin = '221002'
print(bool(re.fullmatch(r'\d{6}', pin)))
print(re.findall(r'\b\w+\b', 'Python is practical!'))
Expected output
True
['Python', 'is', 'practical']

Remember: For complex email addresses, rely on a proper validation strategy rather than a simplistic regex.

Level 9 / 10

9 · Performance and common traps

Strings are immutable. Repeated += in large loops may copy data repeatedly; use a list of parts followed by join(). Remember that is compares identity, not text equality.

Python 3 · runnable example
parts = []
for i in range(4):
    parts.append(str(i))
result = ''.join(parts)
print(result)
print('Apple'.casefold() == 'apple'.casefold())
Expected output
0123
True

Remember: Basic slicing and copying are O(k) for k characters; searching typically scans text.

Level 10 / 10

10 · Mini-project: readable slug

Create a URL-friendly slug. Normalise spacing, keep letters and digits, and join words using hyphens. For multilingual URL rules, design a broader transliteration policy.

Python 3 · runnable example
def slugify(title):
    words = title.casefold().split()
    clean = [''.join(ch for ch in w if ch.isalnum()) for w in words]
    return '-'.join(w for w in clean if w)

print(slugify('  Learn Python 101!  '))
Expected output
learn-python-101

Remember: Challenge: change the function so underscores and repeated punctuation are handled to your specification.

Practice lab

Test your understanding

Predict or explain the answer before opening the solution. Try rewriting one of the examples without copying it.

1. What does 'hello'[1:4] return?

Answer: ell

stop is excluded.

2. Why does name.upper() not modify name?

Answer: Strings are immutable; upper() returns a new string.

Assign the result to a variable.

3. When is ''.join(parts) better than repeated concatenation?

Answer: When assembling many pieces of text.

Collect parts in a list first.

Take it further: expand the mini-project with an input() prompt, a reusable function, input validation and three tests (normal, empty and boundary cases).

When to use each Python collection

Comparison of Python built-in data types
TypeOrdered?Mutable?Duplicates?Best for
strYesNoYesText
listYesYesYesChanging sequences
tupleYesNo*YesFixed records
setNo guaranteed orderYesNoUnique membership
dictInsertion orderYesKeys uniqueNamed lookups

* A tuple itself cannot be reassigned, but a mutable item stored inside it can still change.

Python official built-in types reference ↗

Programmer's Picnic · Developed and maintained by Champak Roy · Practice with real Python, one step at a time.