python / cpython

The Python programming language
https://www.python.org
Other
63.15k stars 30.24k forks source link

Add length counter for iterables #76353

Closed 89f4240f-251b-48e9-858b-0ad5ad4ede03 closed 6 years ago

89f4240f-251b-48e9-858b-0ad5ad4ede03 commented 6 years ago
BPO 32172
Nosy @stevendaprano, @bitdancer

Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

Show more details

GitHub fields: ```python assignee = None closed_at = created_at = labels = ['type-feature', '3.8'] title = 'Add length counter for iterables' updated_at = user = 'https://bugs.python.org/bugalebugale' ``` bugs.python.org fields: ```python activity = actor = 'r.david.murray' assignee = 'none' closed = True closed_date = closer = 'steven.daprano' components = ['Demos and Tools'] creation = creator = 'bugale bugale' dependencies = [] files = [] hgrepos = [] issue_num = 32172 keywords = [] message_count = 3.0 messages = ['307271', '307274', '307459'] nosy_count = 3.0 nosy_names = ['steven.daprano', 'r.david.murray', 'bugale bugale'] pr_nums = [] priority = 'normal' resolution = 'rejected' stage = 'resolved' status = 'closed' superseder = None type = 'enhancement' url = 'https://bugs.python.org/issue32172' versions = ['Python 3.8'] ```

89f4240f-251b-48e9-858b-0ad5ad4ede03 commented 6 years ago

I have noticed that there is no convenient way in python to get the number of items in a generator.

For example: my_iterable = iter(range(1000)) len(my_iterable) # Would not work

Of course, something like this would ruin the generator, and it will no longer be usable, but in some use cases one would like to know only the count of something.

It is possible to do it today using this line: sum(1 for x in my_iterable)

but it seems odd to me that there is no function like: itertools.count_iterable(my_iterable) that does exactly this

stevendaprano commented 6 years ago

Not every trivial one-liner needs to be in the standard library. In this case, there are two easy (and obvious) ways to do it:

sum(1 for x in iterator)

len(list(iterator))

(The first probably saves memory; the second probably is faster.)

Given how rare it is to care ONLY about the length of an iterator, I see no reason why this needs to be in the std lib. If you disagree, please take it to the Python-Ideas mailing list to get community support first before re-opening this ticket.

bitdancer commented 6 years ago

Guido specifically rejected __len__ for iterators when the iteration protocol was designed. This has become a FREQ in recent times (Frequently Rejected Enhancement Request :)

The rationale, as I understand it, is that an iterator object should always evaluate to True in a boolean context, but I don't know why. There is also a consistency argument: since not all iterators *can* have a len, then none should, because if some did and some didn't you couldn't use iterators interchangeably in code the way you can now. In other words, you can't make __len part of the iterator protocol, so iterators don't have a __len.