import dis
deftest_in(x, y):
return x in y
deftest_not_in(x, y):
return x notin y
print("x in y:")
dis.dis(test_in)
print("\nx not in y:")
dis.dis(test_not_in)
# CONTAINS_OP 0 = 'in', CONTAINS_OP 1 = 'not in'# Internally calls PySequence_Contains which:# 1. Tries __contains__# 2. Falls back to iteration
# For loop 'in' uses a different opcode (GET_ITER/FOR_ITER)
deffor_in():
for x in [1, 2, 3]:
passprint("\nfor x in y (different opcode):")
dis.dis(for_in)
Output
Click "Run" to execute your code
'in' for membership compiles to CONTAINS_OP, while 'in' in for loops compiles to GET_ITER + FOR_ITER. They look the same in source but are completely different operations.
Challenge
Try modifying the code above to explore different behaviors. Can you extend the example to handle a new use case?