Skip to content
VLSI Mentor

Python Part I · Module 4 · Strings

Length and Membership

Two questions come up about text more than all the others combined: how long is it, and does it contain this. Python answers the first with len() and the second with the membership operator you already met in Module 3. Neither is complicated, which is exactly why this chapter can afford to be precise about the details that matter — that len() counts characters and not keystrokes, that membership on text looks for a whole run of characters rather than a single one, that it is case-sensitive, and that the empty string is contained in everything. This is also the chapter that explains why len() is written differently from every string operation you have met so far.

Foundation11 min readPythonPart IFundamentalsStringsMembership

Part I · Module 4 · Chapter 4.6 · Length and Membership

1. len(): How Many Characters

Four chapters have used len() as evidence and promised to explain it here. This is that explanation, and it is short, because the idea is exactly what it looks like: len() gives the number of characters in a string.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
line = "UVM_ERROR: scoreboard mismatch"
print(len(line))
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
30

Thirty characters, counting the letters, the colon and the two spaces. Everything between the quotes counts, and nothing else does — the quotes themselves are boundary markers, not characters, as Chapter 1.8 established.

The edges are worth seeing because they come up in practice:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
print(len(""))
print(len("P"))
print(len("  "))
print(len("a b"))
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
0
1
2
3

The empty string has length 0. That is not an error or a special case — it is a string with no characters, and asking how many characters it has sensibly gives zero. Spaces are characters and are counted; " " is genuinely two characters long.

And, as Chapters 4.2 and 4.4 insisted, an escape sequence is one character:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
print(len("PASS\n"))
print(len("a\tb"))
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
5
3

"PASS\n" is five characters: P, A, S, S, newline. If you counted six you counted keystrokes rather than characters.

2. Why len(x) and Not x.len()

Chapter 4.1 taught you value.method(), and you have since seen raw.strip() in that form. So why is length written len(line) rather than line.len()?

Try the other way and Python is clear:

Azvya Education Pvt. Ltd.VLSI Mentor
BROKEN ON PURPOSE
print("abc".len())
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
AttributeError: 'str' object has no attribute 'len'

AttributeError means: you asked this value for something it does not have. There is no len operation attached to strings, because len() is a built-in function rather than a string method.

The practical difference is about generality. A method belongs to one kind of value — strip is a string operation and only strings have it. len() is written to work on anything with a countable number of items, which is why the same len() will measure the lists in Module 5 and the dictionaries in Module 8 without you learning anything new.

So the rule is just a matter of remembering which is which:

FormWhat it isExamples
len(text)a built-in function, value in the parentheseslen, print, str, int, type
text.strip()a method, value before the dotstrip, lower, split, replace

You already know every function in that first row from Modules 1 and 2.

len() does refuse values that have no sensible count:

Azvya Education Pvt. Ltd.VLSI Mentor
BROKEN ON PURPOSE
print(len(4210))
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
TypeError: object of type 'int' has no len()

A number is a single quantity, not a collection of things, so there is nothing to count. Note this is different from len("4210"), which is 4 — the text has four characters. That distinction is Chapter 2.9's point about "4210" not being 4210, showing up again.

3. Membership on Text

Chapter 3.6 taught the membership operators, so you already know that in produces a bool. What this section adds is what membership means when the thing on the right is a string.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
line = "UVM_ERROR: scoreboard mismatch"
print("UVM_ERROR" in line)
print("mismatch" in line)
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
True
True

The important detail: the left operand can be a whole run of characters, not just one. "UVM_ERROR" in line is asking "do these nine characters appear consecutively somewhere in line" — and they do, at the start.

A run of characters appearing inside a larger string is called a substring, and that is the term worth adopting: in tests whether one string is a substring of another.

It works for a single character too, because a single character is just a very short substring:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
line = "UVM_ERROR: scoreboard mismatch"
print("_" in line)
print("z" in line)
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
True
False

And not in asks the opposite question, which often reads better than negating:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
line = "UVM_ERROR: scoreboard mismatch"
print("UVM_FATAL" not in line)
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
True

There is no UVM_FATAL in the line, so not in is True. Chapter 3.5 would let you write not ("UVM_FATAL" in line) instead; not in means the same thing and reads as English.

4. The Details That Bite

It is case-sensitive

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
line = "UVM_ERROR: scoreboard mismatch"
print("ERROR" in line)
print("error" in line)
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
True
False

"ERROR" is there. "error" is not, because E and e are different characters. This is the most common surprise in the chapter and it is not a quirk — it follows from strings being exact sequences of characters.

It also matters in practice, because tools are not consistent about case. Chapter 4.7 is largely about normalising text so that comparisons like this stop depending on it.

Order matters

A substring must appear as a consecutive run, in order:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
print("board" in "scoreboard")
print("scoreboard" in "board")
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
True
False

The first is True — board really is the tail of scoreboard. The second is False: scoreboard is longer than board, so it cannot possibly fit inside it. Membership is not symmetric, and getting the operands the wrong way round is a real bug — it just quietly answers a different question.

The empty string is in everything

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
line = "UVM_ERROR: scoreboard mismatch"
print("" in line)
print("" in "")
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
True
True

Both True, including the empty string containing itself. This looks like a puzzle but is the only consistent answer: the empty string is a run of zero characters, and a run of zero characters appears at every position of every string — including at position 0 of an empty one.

It matters in one practical way. If the marker you are searching for came from somewhere else and happens to be empty, the test will pass on every line, and nothing will look wrong.

The left operand has to be a string

Azvya Education Pvt. Ltd.VLSI Mentor
BROKEN ON PURPOSE
print(42 in "4210")
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
TypeError: 'in <string>' requires string as left operand, not int

The message is unusually direct. When the right-hand side is a string, the left must be too — Python will not convert the number for you and go looking for its digits. Chapter 2.11's str() is the fix if that is genuinely what you want: str(42) in "4210" is True.

5. Both Are Just Expressions

Neither of these is a special construct. Both are ordinary expressions from Module 3 and combine like any others.

A membership test evaluates to a bool you can name:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
line = "UVM_ERROR: scoreboard mismatch"
found = "ERROR" in line
print(found)
print(type(found))
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
True
<class 'bool'>

And both combine with the operators from Module 3:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
line = "UVM_ERROR: scoreboard mismatch"
print(("ERROR" in line) and (len(line) > 10))
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
True

Chapter 3.8 would tell you the brackets are not strictly required there, and would also tell you to keep them — a reader should not have to work out whether in binds tighter than and.

len() also works on the results of Chapter 4.5, because a slice is a string:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
line = "UVM_ERROR: scoreboard mismatch"
print(len(line[0:9]))
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
9

Wall 0 to wall 9, nine characters — which is the stop - start rule confirming itself.

6. Predict, Run, Observe

Predict all six before reading on.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
line = "  PASS: axi_smoke  "
print(len(line))
print("PASS" in line)
print("pass" in line)
print(" " in line)
print(len(line[2:6]))
print("axi_smoke" in line)

The verified output:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
19
True
False
True
4
True

The length is 19, not 15 — the two leading and two trailing spaces are characters like any others. If you predicted 15 you counted only the visible text, which is exactly the mistake Chapter 4.7 exists to prevent.

"pass" in line is False on case alone. " " in line is True because a single space is a substring like any other. And len(line[2:6]) is 4 by the stop - start rule, without needing to know what those characters are.

7. Exercises

Exercise 1 — count precisely. Without running anything, give the length of each, then verify: (a) "FAIL" (b) "" (c) " " (d) "a\nb\nc" (e) "C:\\runs" (f) "4210"

Exercise 2 — function or method. For each, say whether it is written as a function or a method, and correct the ones that are written the wrong way: (a) len(name) (b) name.len() (c) name.strip() (d) strip(name)

Exercise 3 — predict membership. Given entry = "WARNING: hold violation at U12", say True or False for each and explain the two that surprise you: (a) "WARNING" in entry (b) "warning" in entry (c) "violation" in entry (d) "U12" in entry (e) "" in entry (f) "hold violation" in entry (g) "violation hold" in entry

Exercise 4 — the wrong way round. This is meant to test whether the line mentions an error but always prints False. Say what question it actually asks, and fix it:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
line = "UVM_ERROR: mismatch"
print(line in "UVM_ERROR")

Exercise 5 — the empty marker. Explain in two sentences why a search for an empty marker succeeds on every line, and why that makes it a dangerous default.

Exercise 6 — measure a slice. Given row = "axi_smoke PASS", predict len(row), len(row[:9]) and len(row[9:]), then verify. Say in one sentence why the last two must add up to the first.

Exercise 7 — number or text. Predict the result of each, then run them. One of them raises; say which and why: (a) len("4210") (b) len(4210) (c) "42" in "4210" (d) 42 in "4210"

8. Summary

  • len(text) is the number of characters in the value — not the number of keystrokes in the literal.
  • The empty string has length 0, and spaces are characters that count.
  • An escape sequence is one character, so len("PASS\n") is 5.
  • len() is a built-in function, not a method. "abc".len() is an AttributeError. It is a function so that it can measure lists, dictionaries and more later on with no new syntax.
  • len() refuses a number — TypeError: object of type 'int' has no len(). But len("4210") is 4.
  • "sub" in text tests whether one string is a substring of another, and the left operand can be a whole run of characters.
  • Membership on text is case-sensitive. "error" in "ERROR: x" is False.
  • Membership is not symmetric. "board" in "scoreboard" is True; the reverse is False.
  • The empty string is a substring of every string, including itself.
  • The left operand must be a string — 42 in "4210" is a TypeError. Convert with str().
  • Both are ordinary expressions and combine with everything from Module 3.

You can now ask about text. The next chapter starts changing it — beginning with the stray whitespace that made the length 19 rather than 17.

Where this fits

Part of the Python curriculum.