Courses/Python Mastery/Module 4: Operators
Module 4 · Lesson 515 minBeginner

Membership & Identity: in, is

Lesson goal
Check what's inside what — and the is-vs-== trap everyone falls into.

Membership & Identity: in, is

Two operators, two different questions: in asks "is this inside that?" and is asks "is this literally that same thing?" Both return booleans, and both are everywhere in real Python.

in — the membership check

code
email = "galvan@techwithgalvan.in"

print("@" in email)          # True
print("gmail" in email)      # False
print("@" not in email)      # False — not flips it

Works on strings (substring check), and later on lists, dicts, and more:

code
languages = ["Python", "Go", "Rust"]
print("Go" in languages)         # True
print("Java" in languages)       # False

student = {"name": "Aarav", "age": 16}
print("name" in student)         # True — checks KEYS in dicts

That last one matters: for dictionaries, in checks keys, not values.

Where in shines: validation

code
# Password policy
password = input("Password: ")
if "@" in password or "!" in password:
    print("Good — contains a special character")

# Email sanity check
email = input("Email: ")
if "@" not in email:
    print("That does not look like an email")

You already used in for substring checks in the strings lesson — now you know it is a full operator family with not in as its partner.

is — the identity check

is does not compare values. It asks whether two names point to the same object in memory:

code
a = [1, 2, 3]
b = [1, 2, 3]
c = a

print(a == b)    # True  — same VALUE
print(a is b)    # False — different objects in memory!
print(a is c)    # True  — same object, two labels

Picture it: a and c are two labels on one box. b is a different box holding identical contents. == compares contents; is compares boxes.

The one place you should use is: None

code
result = None

if result is None:
    print("No result yet")

if result is not None:
    print("We have a result")

Checking against None with is is the Python community standard. For everything else — numbers, strings — use ==.

The is-vs-equals trap (why beginners get burned)

Small integers and short strings are cached by Python, which makes is *appear* to work like ==:

code
a = 100
b = 100
print(a is b)    # True — cached small int, SAME object (implementation detail!)

a = 1000
b = 1000
print(a is b)    # Often False in scripts — different objects

Do not rely on that. The rule:

ComparingUse
Values (numbers, strings, lists)== / !=
Against Noneis / is not
"Is it this exact object?" (rare)is

Common Errors & Fixes

  • `in` on a dict returns True unexpectedly — it checks keys, not values. For values: "Aarav" in student.values().
  • `x is 5` works but is wrong — it happens to pass for small numbers; use == for values.
  • `TypeError` using `in` on a number5 in 12345 is meaningless; in needs a collection or string on the right.

  • ✅ Checkpoint

  • What does "py" in "python" return? *(True)*
  • For a dict d, does "x" in d check keys or values? *(Keys)*
  • a = [1]; b = [1]a == b? a is b? *(True, False)*
  • How do you check "result has no value"? *(result is None)*
  • Module 4 checkpoint reached — every operator family is now yours. Next: 🧪 Practice, ten quick-fire exercises across all of them.