This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: Improve documentation for list methods that compare items by equality
Type: enhancement Stage: resolved
Components: Documentation Versions: Python 3.7
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: docs@python Nosy List: Alexander Todorov, barry, docs@python, josh.r, steven.daprano, xiang.zhang
Priority: normal Keywords:

Created on 2017-03-08 14:03 by Alexander Todorov, last changed 2022-04-11 14:58 by admin. This issue is now closed.

Pull Requests
URL Status Linked Edit
PR 572 merged xiang.zhang, 2017-03-09 04:59
Messages (9)
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) * (Python committer) 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) * (Python committer) 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) * (Python committer) 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) * (Python triager) 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) * (Python committer) 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) * (Python committer) 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) * (Python committer) 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
History
Date User Action Args
2022-04-11 14:58:44adminsetgithub: 73942
2017-03-24 22:20:58xiang.zhangsetmessages: + msg290190
2017-03-13 02:11:02xiang.zhangsetstatus: open -> closed
stage: resolved
resolution: fixed
versions: + Python 3.7
2017-03-13 01:28:02steven.dapranosetmessages: + msg289519
2017-03-12 21:53:16Alexander Todorovsetmessages: + msg289512
2017-03-09 04:59:26xiang.zhangsetpull_requests: + pull_request468
2017-03-09 04:07:31xiang.zhangsetnosy: + xiang.zhang
messages: + msg289270
2017-03-08 15:35:23josh.rsetnosy: + josh.r
messages: + msg289243
2017-03-08 15:10:15steven.dapranosetmessages: + msg289240
2017-03-08 15:01:57steven.dapranosetstatus: closed -> open

resolution: not a bug -> (no value)

assignee: docs@python
stage: resolved -> (no value)
title: List count() counts True as 1 -> Improve documentation for list methods that compare items by equality
nosy: + steven.daprano, docs@python
versions: - Python 2.7, Python 3.5
messages: + msg289239
components: + Documentation
type: enhancement
2017-03-08 14:29:18barrysetstatus: open -> closed

nosy: + barry
messages: + msg289236

resolution: not a bug
stage: resolved
2017-03-08 14:03:53Alexander Todorovcreate