JJoeven

Curriculum/Python

Compare and Combine Values

Use ==, !=, <, in, is, and, or, not. Know same value versus same object, short-circuit, and beginner traps.

beginner18 min4 / 37

An operator is a symbol that compares or combines values. Agents use these all day: is the step still under the budget, is the tool name allowed, is the error still missing.

A comparison gives you True or False. You then use that answer in if, in while, or in a print while you debug. If you write step = 3 you store 3. If you write step == 3 you ask a question. Mixing those two is a classic bug.

Compare values

OperatorMeaningExample
==same valuestep == 3
!=not the same valuestep != 8
< <= > >=less / morestep < budget
infound inside"search" in text
issame objecterror is None

== asks: do these have the same value? is asks: are these the same object?

An object is the actual value in memory. A name is a label stuck on that object. Two rows can hold the same numbers. That is ==. Two names stuck on one row is is.

A comparison is a yes or no
step == 3TrueFalse

== asks if the values match. is asks if two names point at the same object. Use is for None.

A comparison is a yes or no

You can chain comparisons: 0 < step < budget. That is true when step is greater than 0 and also less than budget. It reads like math. It is legal Python. step < budget and step > 0 is the same idea with and.

Same value vs same object

A list is a row of values in square brackets, like [1, 2].

python
a = [1, 2]
b = [1, 2]
c = a
print(a == b)  class="tok-c"># True — same values
print(a is b)  class="tok-c"># False — two different rows
print(a is c)  class="tok-c"># True — same row, two names

Use == for numbers, text, and “does this match.” Use is for None. Do not use is to compare numbers or text. Small numbers can look like the same object by accident. That trick will confuse you. step is 3 might print True in a demo and False tomorrow. step == 3 is the check you meant.

None is missing. There is only one None. So error is None is the usual check. error == None often works, but style and a few edge cases prefer is. Learn is None and is not None.

in

in asks if something is found inside something else.

  • "act" in "action" is True
  • "search" in ["read", "search"] is True
  • 3 in [1, 2, 3] is True

Watch out: "error" in "terror" is also True, because those letters sit inside the word. For a careful check, compare full words, or add spaces, or use == against a list of allowed names.

On a dict (named fields, later lesson), in checks keys, not values. "name" in action might be True while "search" in action is False. Do not use in on a dict until you know you are asking about keys.

not in is the opposite: "write" not in allowed is a good unknown-tool guard.

Combine with and, or, not

  • not x flips yes and no
  • x and y is yes only if both are yes
  • x or y is yes if at least one is yes
python
step = 3
budget = 8
print(step < budget and step > 0)
print(step == 99 or step == 3)
print(not False)
print(not (step == 3))

Parentheses help when you mix and and or. and binds tighter than or, the way multiply binds tighter than add. If you have to look it up, use parentheses. Clear checks beat clever checks.

not applies to one value. not step < budget is easy to misread. Write not (step < budget) or step >= budget.

Short-circuit

Short-circuit means stop early.

  • and does not look at the right side if the left side is already False
  • or does not look at the right side if the left side is already True

That is useful. You can write name or "guest". If name is empty, you get "guest". If name has text, you keep name. You can write error is None and step < budget and the second check never runs if error is already set.

Empty text "" counts as no in this kind of check. Zero counts as no. None counts as no. We will go deeper on that in the True/False lesson. Do not use or "guest" when 0 is a legal measurement you must keep.

Read a check out loud

Before you put a comparison in an if or a while, print it. print("under budget", step < max_steps) is not a toy. It is how you confirm the operator did what you think. Beginners often write step < max_steps when they meant step <= max_steps. The difference is whether you are allowed to use the last slot. A budget of 8 with < allows steps 0 through 7 if you count from zero, or 1 through 7 if you already incremented. Print step next to the boolean and you will see.

not in is the unknown-tool check: if name not in allowed. That is clearer than if not name in allowed, which is legal but easy to misread. Parentheses around the membership test are optional. Readability is not.

When both sides are strings, < uses dictionary order: "a" < "b" is True. Do not sort version numbers as strings if you can avoid it. Do not compare a tool name to a number. Mixed-type ordering can error or, worse, quietly be False.

Common mistakes

  • Writing = when you meant ==. Assignment does not ask a question.
  • Using is for strings or numbers.
  • "error" in "terror" treated as a real error flag.
  • Forgetting parentheses: not a == b is (not a) == b, which is rarely what you wanted. Write a != b or not (a == b).
  • Comparing mixed types: "3" == 3 is False, not an error. The check is quiet and wrong.
Live PythonOpen full playgroundpython
Output
Run to execute this in your browser. Nothing is sent to a server.

Read "error" in "terror" out loud. Then imagine a tool result that contains the word “terror” and an agent that stops because it thought it saw “error.” That is why exact checks matter.

How agents use this

Agents compare on every turn: step vs budget, tool name in the allowed list, and error is None. Use == for values. Use is for None. Combine checks with and and or, and remember they can stop early.

A clear stop rule looks like step < max_steps and not done and error is None. Each piece is one question. If you pack five ideas into one clever line, you will not know which piece flipped when the loop dies.

Allowlists use in on a list or a set of tool names. That is a full-name check: "search" in allowed. Do not use substring in on a blob of model text to decide whether a tool ran. Parse the action into a name, then compare the name.

Traces should print the boolean that caused a branch: print("under budget", step < max_steps). When the agent stops early, you want that line in the log. Operators are how the loop chooses. Printing the choice is how you debug it.

Check your understanding

You have a = [1, 2] and b = [1, 2]. What is true?