You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+109-6
Original file line number
Diff line number
Diff line change
@@ -261,26 +261,131 @@ some_dict[5] = "Python"
261
261
"Ruby"
262
262
>>> some_dict[5.0]
263
263
"Python"
264
-
>>> some_dict[5]
264
+
>>> some_dict[5] # "Python" destroyed the existence of "JavaScript"?
265
+
"Python"
266
+
267
+
>>>complex_five=5+0j
268
+
>>>type(complex_five)
269
+
complex
270
+
>>> some_dict[complex_five]
265
271
"Python"
266
272
```
267
273
268
-
"Python" destroyed the existence of "JavaScript"?
274
+
So, why is Python all over the place?
275
+
269
276
270
277
#### 💡 Explanation
271
278
272
279
* Python dictionaries check for equality and compare the hash value to determine if two keys are the same.
273
280
* Immutable objects with same value always have the same hashin Python.
274
281
```py
275
-
>>>5==5.0
282
+
>>>5==5.0==5+0j
276
283
True
277
-
>>>hash(5) ==hash(5.0)
284
+
>>>hash(5) ==hash(5.0)==hash(5+0j)
278
285
True
279
286
```
280
287
**Note:** Objects with different values may also have same hash (known ashash collision).
281
288
* When the statement `some_dict[5] = "Python"`is executed, the existing value "JavaScript"is overwritten with"Python" because Python recognizes `5`and`5.0`as the same keys of the dictionary `some_dict`.
282
289
* This StackOverflow [answer](https://stackoverflow.com/a/32211042/4354153) explains beautifully the rationale behind it.
>>>len({ordered_dict, another_ordered_dict, dictionary}) # changing the order
348
+
2
349
+
```
350
+
351
+
What is going on here?
352
+
353
+
#### 💡 Explanation:
354
+
355
+
- The reason why intransitive equality didn't hold among `dictionary`, `ordered_dict` and `another_ordered_dict` is because of the way `__eq__` method is implemented in `OrderedDict` class. From the [docs](https://docs.python.org/3/library/collections.html#ordereddict-objects)
356
+
> Equality tests between OrderedDict objects are order-sensitive and are implemented as`list(od1.items())==list(od2.items())`. Equality tests between `OrderedDict` objects and other Mapping objects are order-insensitive like regular dictionaries.
357
+
- The reason for this equality is behavior is that it allows `OrderedDict` objects to be directly substituted anywhere a regular dictionary is used.
358
+
- Okay, so why did changing the order affect the lenght of the generated `set`object? The answer is the lack of intransitive equality only. Since sets are "unordered" collections of unique elements, the order in which elements are inserted shouldn't matter. But in this case, it does matter. Let's break it down a bit,
359
+
```py
360
+
>>>some_set=set()
361
+
>>> some_set.add(dictionary) # these are the mapping objects from the snippets above
362
+
>>> ordered_dict in some_set
363
+
True
364
+
>>> some_set.add(ordered_dict)
365
+
>>>len(some_set)
366
+
1
367
+
>>> another_ordered_dict in some_set
368
+
True
369
+
>>> some_set.add(another_ordered_dict)
370
+
>>>len(some_set)
371
+
1
372
+
373
+
>>>another_set=set()
374
+
>>> another_set.add(ordered_dict)
375
+
>>> another_ordered_dict in another_set
376
+
False
377
+
>>> another_set.add(another_ordered_dict)
378
+
>>>len(another_set)
379
+
2
380
+
>>> dictionary in another_set
381
+
True
382
+
>>> another_set.add(another_ordered_dict)
383
+
>>>len(another_set)
384
+
2
385
+
```
386
+
So the inconsistency is due to `another_ordered_dict in another_set` being False because `ordered_dict` was already present in`another_set`andas observed before, `ordered_dict == another_ordered_dict`is`False`.
0 commit comments