0

Reading through this really cool online book, Speaking JS, I came across a neat quirk illustrating how comparisons work in JavaScript:

Primitive values are "Compared by value":

> 3 === 3
true
> 'abc' === 'abc'
true

Objects, however, are "Compared by reference":

> {} === {}  // two different empty objects
false
> var obj1 = {};
> var obj2 = obj1;
> obj1 === obj2
true

A co-worker and I were chatting about this and wondered if the principle holds for Python.

So we cracked open a Python interpreter to see if this comparison works differently in that language.

>>> 3 == 3
True
>>> {} == {}
True

Turns out, two dictionaries resolve as equal in Python if their contents are the same.

Does this mean that Python dictionaries are "Compared by value"?

Is there a way to compare Python dictionaries by reference?

fzzle
  • 1,466
  • 5
  • 23
  • 28
SeanPlusPlus
  • 8,663
  • 18
  • 59
  • 84

1 Answers1

4

In Python, the == operator compares by value. According to the Python 2.7 documentation:

The operators is and is not test for object identity.

See the following example:

print({} is {}) # False
print({} == {}) # True

As Ignacio Vazquez-Abrams said, note that this does not necessarily hold for all values. For example, 9 is 9 is true in some implementations, but don't count on it. Basically, the reason why is that number values may be simply a reference to a single object for all references of the same value, or separate objects . For example, CPython uses references for numbers between -5 and 256, inclusive (for a more detailed explanation, see this question).

print(9 is 9) # dependent on implementation
print(9 == 9) # True
Community
  • 1
  • 1
Qantas 94 Heavy
  • 15,750
  • 31
  • 68
  • 83
  • 1
    But don't be fooled by the result for `3 is 3`. – Ignacio Vazquez-Abrams Mar 21 '14 at 22:51
  • Also don't be fooled by the corner case: `id({}) == id({})` which is in the same vein, but a little different. – mgilson Mar 21 '14 at 22:52
  • @mgilson: interesting -- don't have too much Python experience, but would that be because the lifetime of the two dictionaries don't overlap? – Qantas 94 Heavy Mar 21 '14 at 23:09
  • @Qantas94Heavy -- That's exactly it. Note that the output of that statement is completely implementation dependent. The Cpython memory allocator makes it very likely that the second dict will be put in the same memory location that the original dictionary lived in (and `id` returns the memory address for CPython). It's not behavior you should count on though :-) – mgilson Mar 21 '14 at 23:13
  • There is no such thing as a primitive value as opposed to an object, and although ints are indeed treated differently in some regards relevant to this question, `is` doesn't work differently for them and `i == j` does not imply `i is j` as the last snippet would imply. –  Mar 21 '14 at 23:21