Strings in Python
Strings show up constantly in DSA: palindromes, anagrams, parsing, and pattern matching. In Python a string behaves like an immutable sequence of characters, so much of what you learned about lists applies here too.
Strings are immutable#
You can read a character by index, but you cannot change one in place:
1word = "algorithm"
2print(word[0]) # 'a'
3print(word[-1]) # 'm'
4# word[0] = "A" # TypeError: strings cannot be modified
To “change” a string, build a new one. This immutability matters for performance: repeatedly adding to a string in a loop creates many copies.
Slicing works just like lists#
1s = "abcdef"
2print(s[1:4]) # 'bcd'
3print(s[:3]) # 'abc'
4print(s[::-1]) # 'fedcba' (reversed, a one-line palindrome helper)
Reversing with s[::-1] gives you an instant palindrome check:
1def is_palindrome(s):
2 return s == s[::-1]
3
4print(is_palindrome("racecar")) # True
5print(is_palindrome("hello")) # False
Useful string methods#
1text = " Hello World "
2print(text.strip()) # 'Hello World' (trim whitespace)
3print(text.lower()) # ' hello world '
4print("a,b,c".split(",")) # ['a', 'b', 'c']
5print("-".join(["a", "b"])) # 'a-b'
6print("hello".find("ll")) # 2 (index, or -1 if absent)
7print("hello".replace("l", "L")) # 'heLLo'
split and join are a common pair: split a sentence into words, process them, then join them back.
Building strings efficiently#
Because strings are immutable, concatenating inside a loop with + is slow (it copies each time). Collect pieces in a list and join once:
1# Slow for large loops:
2result = ""
3for ch in "abc":
4 result += ch
5
6# Preferred:
7pieces = []
8for ch in "abc":
9 pieces.append(ch)
10result = "".join(pieces)
11print(result) # 'abc'
The join approach is O(n) overall instead of O(n squared). See the Big-O cheat sheet for why repeated copying adds up.
Characters and codes#
Sometimes you need the numeric code of a character, for example to map letters to array positions:
1print(ord("a")) # 97
2print(chr(97)) # 'a'
3print(ord("c") - ord("a")) # 2 (offset of 'c' from 'a')
That offset trick is common when counting letters with a fixed-size list of 26 slots.
An anagram example#
1from collections import Counter
2
3def is_anagram(a, b):
4 return Counter(a) == Counter(b)
5
6print(is_anagram("listen", "silent")) # True
Next: functions and recursion, where you start structuring your own algorithms.