Skip to content
VLSI Mentor

Python Part I · Module 3 · Operators and Expressions

Membership and Identity: in, not in, is

Two operators that answer questions the ones so far cannot. The first, in, asks whether something appears inside something else — whether a marker is present in a line of text, for instance — and it is one of the most useful things in Python precisely because it reads exactly like the English word. The second, is, looks deceptively similar to the equality comparison from Chapter 3.4 and asks something genuinely different. That difference causes real bugs when people treat the two as interchangeable, so this chapter takes a deliberately narrow position on it: there is one everyday use of is that you should adopt as a habit, and outside that one case the honest advice for now is to use the equality comparison instead.

Foundation9 min readPythonPart IFundamentalsMembershipIdentity

Part I · Module 3 · Chapter 3.6 · Membership and Identity: in, not in, is

1. Does This Appear Inside That?

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
line = "0 errors, 3 warnings"

print("errors" in line)
print("FATAL" in line)
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
True
False

in asks whether something appears inside something else, and produces a bool — so it is an expression like every other one in this module.

Read it as the English word. Is "errors" in line? Yes. Is "FATAL" in line? No.

There is a negative form that reads just as naturally:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
line = "0 errors, 3 warnings"

print("FATAL" not in line)
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
True

not in is one operator, written as two words. It is the same question with the answer flipped, and it reads better than wrapping the whole thing in not.

2. What Counts as Inside

For text, in looks for the characters appearing in sequence anywhere in the larger piece of text.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
print("err" in "0 errors")
print("rror" in "0 errors")
print("sorre" in "0 errors")
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
True
True
False

"err" and "rror" both appear as runs of characters. "sorre" uses the same letters but not in that order, so it does not.

It is also case-sensitive, exactly as == was in Chapter 3.4 §4:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
print("ERRORS" in "0 errors")
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
False

3. Why This Is Worth Having

A single readable line replaces a surprising amount of work:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
line = "UVM_ERROR @ 1200 ns: scoreboard mismatch"

print("UVM_ERROR" in line)
print("UVM_FATAL" in line)
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
True
False

That is the core of every log checker ever written. In Part II it appears inside a loop over a file, but the test itself is exactly this line and nothing more.

4. A Different Question: is

Now the second half, and it needs care.

Chapter 3.4 taught ==, which asks do these two values compare equal?

is asks something else: are these two names referring to the very same value? Not an equal one — the same one.

That sounds like a fine distinction and usually it does not matter, which is exactly why people reach for is when they mean == and get away with it until they do not.

5. The One Use You Should Adopt

Here is the rule worth taking away:

To check whether something is None, use is None.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
first_error = None
print(first_error is None)

first_error = "timeout"
print(first_error is None)
print(first_error is not None)
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
True
False
True

is not is the negative form, written as two words like not in.

Why this rather than == None? Because there is exactly one None in Python — Chapter 2.8 §5 said it is the only value of its type. So "is this the None value" is precisely an identity question, and is None says exactly what is meant.

== None usually gives the same answer, but it asks a subtly different question, and is None is what every Python codebase you will read uses.

6. Do Not Use is for Anything Else Yet

Being direct about this, because the alternative is a habit that produces intermittent bugs.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
a = 4210
b = 4210
print(a == b)
print(a is b)
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
True
True

Both answered True, which looks like confirmation that the two operators are interchangeable. They are not. That second answer depends on how Python happened to produce those two values, and it is not something to rely on.

Here is the same question where the value is worked out while the program runs rather than written down directly:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
a = 500000
b = 499999
b += 1

print(a == b)
print(a is b)
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
True
False

a and b now hold the same number — == says so. But is says False, because they are not the same value; they are two equal ones, arrived at by different routes.

The same thing happens with text:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
name_1 = "axi_smoke"
name_2 = "axi_"
name_2 += "smoke"

print(name_1 == name_2)
print(name_1 is name_2)
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
True
False

Two pieces of text containing exactly the same characters, and is still says no.

Nothing is broken in any of these. is was simply never asking the question you wanted — and notice that the first example, where both were written out directly, gave True and would have let the mistake pass unnoticed.

7. The Four Together

OperatorAsksExampleResult
indoes this appear inside that?"err" in "0 errors"True
not indoes it not appear?"FATAL" not in lineTrue
isis this the very same value?first_error is NoneTrue
is notis it not the same value?first_error is not NoneFalse

All four are expressions producing a bool, so all four combine with and, or and not from Chapter 3.5:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
line = "0 errors, 0 warnings"
first_error = None

print("errors" in line and first_error is None)
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
True

8. Predict, Run, Observe

Predict each, then run.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
line = "TEST DONE: 3 errors"
status = None

print("DONE" in line)
print("done" in line)
print("PASS" not in line)
print(status is None)
print(status is not None)
print("errors" in line and status is None)
print(type("DONE" in line))
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
True
False
True
True
False
True
<class 'bool'>

The second line is the check: "done" is not in the text because membership is case-sensitive, even though "DONE" is.

9. Exercise

Exercise 1 — check a line. Given line = "UVM_WARNING @ 500 ns", write three lines that print whether "UVM_ERROR" appears, whether "UVM_WARNING" appears, and whether "UVM_FATAL" does not appear.

Exercise 2 — the case trap. Predict both, then run:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
line = "0 Errors"
print("errors" in line)
print("Errors" in line)

Explain the difference in one sentence.

Exercise 3 — None or not. Start report_path at None, print whether it is None, then assign it "report.txt" and print again. Use is None both times.

Exercise 4 — pick the operator. For each, say whether you would use ==, is, or in: (a) has the run produced a first failure yet; (b) is the status word exactly "PASS"; (c) does this line mention a fatal; (d) is the error count zero.

Exercise 5 — the unreliable comparison. Predict what each prints, then run:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
a = 300000
b = 299999
b += 1
print(a == b)
print(a is b)

The two answers differ. Say in one sentence which operator you should have used to ask "are these the same number", and why the other one answered as it did.

10. Summary

  • in asks whether something appears inside something else and produces a bool. not in is the negative form.
  • For text, in looks for the characters in sequence, and it is case-sensitive.
  • "UVM_ERROR" in line is the core of every log checker — Part II builds on exactly this.
  • is asks whether two names refer to the very same value, which is a different question from ==.
  • Use is None and is not None. That is the one place is belongs in everyday code, and it is the universal Python convention.
  • Do not use is on numbers or text. It agrees with == sometimes and not others, and the difference is not something to rely on.
  • == compares values; is is for None. Module 16 explains why; the rule holds without it.
  • This is a first look at in. Module 4 covers text membership fully; Modules 5 to 8 extend it to collections.

One operator family remains, and for a semiconductor engineer it is the one that matters most.

Where this fits

Part of the Python curriculum.