On 11/26/2018 4:29 PM, Kale Kundert wrote:
I just ran into the following behavior, and found it surprising:

 >>> len(map(float, [1,2,3]))
TypeError: object of type 'map' has no len()

I understand that map() could be given an infinite sequence and therefore might not always have a length.

The len function is defined as always returning the length, an int >= 0. Hence .__len__ methods should always do the same.
https://docs.python.org/3/reference/datamodel.html#object.__len__
Objects that cannot do that should not have this method.

The previous discussion of this issue lead to function operator.length_hint and special method object.__length_hint__ in 3.4.

https://docs.python.org/3/library/operator.html#operator.length_hint
"""
operator.length_hint(obj, default=0)

Return an estimated length for the object o. First try to return its actual length, then an estimate using object.__length_hint__(), and finally return the default value.

    New in version 3.4.
"""
https://docs.python.org/3/reference/datamodel.html#object.__length_hint__
"""
object.__length_hint__(self)

Called to implement operator.length_hint(). Should return an estimated length for the object (which may be greater or less than the actual length). The length must be an integer >= 0. This method is purely an optimization and is never required for correctness.

    New in version 3.4.
"""

But in this case, it seems like map() should've known that its length was 3.

As others have pointed out, this is not true. If not infinite, the size, defined as the number of items to be yielded, and hence the size of list(iterator), shrinks by 1 after every next call, just as with pop methods.

>>> it = iter([1,2,3])
>>> it.__length_hint__()
3
>>> next(it)
1
>>> it.__length_hint__()
2
>>> list(it)
[2, 3]
>>> it.__length_hint__()
0

Last I heard, list() uses length_hint for its initial allocation. But this is undocumented implementation.

Built-in map does not have .__length_hint__, for the reasons others gave for it not having .__len__. But for private code, you are free to define a subclass that does, with the definition you want.

--
Terry Jan Reedy

_______________________________________________
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to