Python’s string model

A Python str is an immutable sequence of Unicode code points. An interview question may instead mean ASCII letters, bytes, or visible symbols. Establish that contract before you choose a data structure. This course uses code points unless a problem says otherwise.

Learning objective

Distinguish characters, code points, and immutable strings before solving a problem.

Start with the contract

Ask what empty input means, whether case matters, and whether spaces count. “Is this a palindrome?” has different answers under exact comparison and punctuation-free comparison. Do not normalize unless the specification asks you to.

message = "café"
assert len(message) == 4
assert message[0] == "c"
assert message[-1] == "é"
assert "A" != "a"
assert len("e\u0301") == 2

The final example is an e followed by a combining accent: two code points that can look like one letter. Reversing such a string reverses code points, not user-perceived characters.

Immutability changes your approach

You cannot assign to message[0]. Build a new value instead. A loop that inspects characters can use constant auxiliary space; a transformation that returns a new string needs storage for that output. Say which space measure you mean.

Guided practice

Count exact occurrences of a target character. Maintain an integer counter; after visiting the first i characters, the counter must equal the matches in that prefix. This sentence is your first loop invariant.

Check your understanding

Does empty input contain zero characters? Yes. Should A match a under exact equality? No. Can two visually similar strings differ? Yes: normalization is a separate choice.

Independent practice

Try Count a symbol and Equal-length difference count. Explain the input contract aloud before coding.

Takeaway

Choose semantics first, then a representation. Most subtle string bugs begin with an unstated assumption.

Deeper check: Code points, bytes, and display

Python length counts code points, not encoded bytes or visible graphemes. This matters when an interview statement casually says “characters.” Ask which model it intends before normalizing or reversing. The empty string is a real value, distinct from a missing result such as None. A function that returns an index should state which string that index refers to, especially when a transformation changes length.

text = "é🙂"
assert len(text) == 2
assert len(text.encode("utf-8")) == 6
assert "e\u0301" != "é"
assert "" != None

Apply the idea

Explain why reversing e followed by a combining accent can change its appearance. The reversed code-point order places the accent before the base letter; code-point reversal is not grapheme reversal. Continue to the Unicode lesson for an explicit comparison policy.