Everything is an object: identity, type and value
See how Python really stores data: every value is an object with an identity, a type and a value. Watch id() stay put or change, and learn is versus ==.
In Python, every value is an object: numbers, strings, lists, functions, even classes and modules. And every object has three things:
- an identity, which never changes while the object exists.
id(x)shows it as a number (in CPython, the version running here, it's the object's address in memory); - a type, which also never changes:
type(x); - a value, which may or may not be able to change, depending on the type.
A name like x isn't any of these. It's a reference that leads to an object.
Two equal lists, or one list?
== asks "do these have the same value?". is asks "are these the same object?", which is the same as comparing their ids. Run this and compare the numbers:
mine = ["pears", "rice"] yours = ["pears", "rice"] ours = mine print(mine == yours, mine is yours) # True False print(mine == ours, mine is ours) # True True print(id(mine), id(yours), id(ours))
Two of the three ids match. yours was built separately, so it's a second object that happens to hold the same items. ours = mine copied nothing at all: it made a second name for the one list that already existed.
Changing an object, or getting a new one
Watch the id when the value changes:
basket = ["pears"]
print(id(basket))
basket.append("rice")
print(id(basket)) # the same: the list itself changed
count = 10
print(id(count))
count = count + 1
print(id(count)) # different: count now names another objectA list is mutable: append changes the object in place, so its id stays. An int is immutable: there's no way to change the object 10, so count + 1 makes a new object, 11, and the name moves to it. Strings, floats, tuples, True and None are immutable too.
Types are objects too
print(type(42), type("hi"), type(print))
print(type(int)) # <class 'type'>: int is an object whose type is type
say = print # a function is an object: give it another name
say("Hello from say")When to use is
Use == to compare values, almost always. Use is for None: there is only ever one None object, so if result is None: is exact and fast.
Don't use is to compare numbers or strings. Whether two equal values share one object is up to Python, not you:
a = int("256")
b = int("256")
print(a is b) # True: CPython keeps one object for each small int
c = int("1000")
d = int("1000")
print(c is d) # False: two objects, equal valuesPython even warns about it: x is 1000 gets a SyntaxWarning suggesting ==.
More in the Python docs: objects, values and types, id() and identity comparisons.
Your turn
Make twin a new list equal to original but a separate object, and alias another name for original itself. Print the ids of all three (two should match). Then append 40 through alias, print original, and see what happened to it.
Your task
Make twin a new list equal to original but a separate object, and alias another name for original itself. Print the ids of all three (two should match). Then append 40 through alias, print original, and see what happened to it.
- twin is an equal but separate list (not done yet)
- alias is the same object as original (not done yet)
- Print the ids of all three (not done yet)
- Append 40 through alias, then print original (not done yet)
The checklist ticks itself off as you work in the editor: any way that gets the result counts.
Hints come one at a time, then one way to do it. Try each before the next.
What this lesson uses, in one place.
id()- An object’s identity: a number that stays the same for as long as the object exists Python docs →
type()- The type of a value: type(3) is int, type("3") is str Python docs →
is- True when two names refer to the same object (the same id) Python docs →
==- True when two values are equal; for your classes, it calls __eq__ Python docs →
is None- The right way to test for None: there is only one None object Python docs →