msg289235 - (view) |
Author: Alexander Todorov (Alexander Todorov) |
Date: 2017-03-08 14:03 |
When using list.count() I get the following results >>> [1, 2, 3].count(1) 1 >>> [1, 2, 3, True].count(2) 1 >>> [1, 2, 3, True].count(True) 2 >>> [1, 2, 3, True].count(1) 2 as you can see True is considered the same as 1. The documentation for the count method says: count(...) L.count(value) -> integer -- return number of occurrences of value so IMO the above behavior is wrong. Seeing this on a RHEL 7 system with Python 3.5.1 and 2.7.5 |
|
|
msg289236 - (view) |
Author: Barry A. Warsaw (barry) *  |
Date: 2017-03-08 14:29 |
bools are subclasses of int and False and True have integer equivalents: https://docs.python.org/3/library/stdtypes.html#bltin-boolean-values |
|
|
msg289239 - (view) |
Author: Steven D'Aprano (steven.daprano) *  |
Date: 2017-03-08 15:01 |
Further to Barry's explanation, you see the same result with any values which compare equal: py> from decimal import Decimal as D py> [1, 1.0, D(1), True, 1+0j].count(D(1)) 5 This is standard behaviour for methods `count`, `remove`, and `index`, but it isn't explained well in the documentation. E.g. `remove` says "Remove the first item from the list whose value is x` which could be read as meaning that the test is done by identity. All three methods need to clarify that ordinary == equality is used. I'm going to re-open the task as a documentation issue. |
|
|
msg289240 - (view) |
Author: Steven D'Aprano (steven.daprano) *  |
Date: 2017-03-08 15:10 |
To be clear, I'm referring to the docs in the tutorial: https://docs.python.org/3.7/tutorial/datastructures.html and the docstrings as well as the library reference: https://docs.python.org/3.7/library/stdtypes.html#sequence-types-list-tuple-range The library reference already notes that `remove` uses equality, but the others do not. |
|
|
msg289243 - (view) |
Author: Josh Rosenberg (josh.r) *  |
Date: 2017-03-08 15:35 |
Steven: Technically, in CPython, they use both identity and equality testing, as a function of using RichCompareBool (which tests identity first, then equality), rather than RichCompare (which only tests equality). It makes a difference for stuff like NaN values, where describing it as equality only would imply that: nan = float('nan') ([nan] * 10).count(nan) produces 0 (because nan is equal to nothing, including itself), when in fact it produces 10 (because we reused the same nan object, and the identity test passed). |
|
|
msg289270 - (view) |
Author: Xiang Zhang (xiang.zhang) *  |
Date: 2017-03-09 04:07 |
+1 for jsoh. Actually the behaviour is documented in https://docs.python.org/3/reference/expressions.html#value-comparisons. So a single 'a is b' or 'a == b' is not complete. I would like to use 'equal to' which implies 'a is b or a == b'. |
|
|
msg289512 - (view) |
Author: Alexander Todorov (Alexander Todorov) |
Date: 2017-03-12 21:53 |
Hi folks, I have another very similar issue, it could be the same root cause. Let me know if it is. assert 3 == 3.0 will pass self.assertEqual(3, 3.0) - will pass this had the nasty side effect of my test suite not catching a problem with SUT. I have updated the test suite to validate the result type as well but want to know how to file this use-case. |
|
|
msg289519 - (view) |
Author: Steven D'Aprano (steven.daprano) *  |
Date: 2017-03-13 01:28 |
I'm afraid I don't know what SUT means. But 3 == 3.0 is the correct and expected behaviour. If you need to check that two values are both the same type and the same value, you have to validate the type and value separately. Changing the behaviour of == is ruled out for backwards compatability, but perhaps you could suggest a new === operator to check type and value. That would require some discussion on the Python Ideas mailing list, not just a feature request on the tracker. |
|
|
msg290190 - (view) |
Author: Xiang Zhang (xiang.zhang) *  |
Date: 2017-03-24 22:20 |
New changeset b2d77175d1317494b4238b4e07426d310fbf1d19 by Xiang Zhang in branch 'master': bpo-29756: Improve documentation for list methods that compare items by equality (GH-572) https://github.com/python/cpython/commit/b2d77175d1317494b4238b4e07426d310fbf1d19 |
|
|