Python's operators cover the usual arithmetic, comparison, and logical categories, plus a couple of Python-specific identity and membership operators.
print(5 == 5) # True — equality
print(5 is 5) # True for small ints (cached), but risky to rely on for larger objects
print("a" in "cat") # True — membership test, works on strings, lists, dicts, sets
print(3 not in [1,2]) # True
a, b = True, False
print(a and b) # False
print(a or b) # True
print(not a) # False
== checks value equality (do these objects represent the same value?), while is checks identity (are these literally the same object in memory?) — for mutable objects like lists, a == b can be True while a is b is False if they're two separate-but-equal lists; is should be reserved for comparing against singletons like None, True, and False, not for general equality checks.
in/not in test membership — whether a value exists inside a string, list, tuple, dict (checks keys), or set — and read almost like plain English (if "error" in log_line:), one of the clearest examples of Python's readability-focused design.
and, or, and not are the logical operators (spelled out as words rather than &&/||/!), and and/or short-circuit exactly as in other languages, additionally returning one of their actual operands rather than a strict boolean — "" or "default" evaluates to "default", a common idiom for supplying a fallback value.