Reputation: 637
In Luciano Ramalho's Fluent Python, an iterable is defined as an object in which the __iter__
method is implemented, with no additional characteristics.
I am currently working out a tutorial for laymen in which I am trying to chunk the core concepts of Python to make programming more manageable for newcomers.
I find it easier to explain iterables and their utility for these people when I associate these objects with the concept of "size" (thus also length
). By saying that "iterables are objects that have length" and thus tying in with the len
function, I am able to naturally evolve the concept of loops and iteration with commonly used types such as the Standard Library list
, dict
, tuple
, str
, as well as numpy.ndarray
, pandas.Series
and pandas.DataFrame
.
However, since now I know about the sole necessity for the __iter__
method, there can be cases where the analogy with len
fails. Ramalho even provides an impromptu example in his book:
import re
import reprlib
RE_WORD = re.compile(r'\w+')
class Sentence:
def __init__(self, text):
self.text = text
def __repr__(self):
return 'Sentence(%s)' % reprlib.repr(self.text)
def __iter__(self):
for match in RE_WORD.finditer(self.text):
yield match.group()
As expected, any instance of Sentence
is an iterable (I can use for
loops), but len(Sentence('an example'))
will raise a TypeError
.
Since all the aforementioned objects are iterables and have a __len__
method implemented, I want to know if there are relevant objects in Python which are iterables (__iter__
), but do not have lengths (__len__
) so if I can determine whether I just add a footnote to my tutorial or work out a different analogy.
Upvotes: 4
Views: 533
Reputation: 5521
Iterators are ubiquitous iterables that usually don't offer a length:
>>> len(iter('foo'))
Traceback (most recent call last):
File "<pyshell#1>", line 1, in <module>
len(iter('foo'))
TypeError: object of type 'str_iterator' has no len()
>>> len(iter((1, 2, 3)))
Traceback (most recent call last):
File "<pyshell#3>", line 1, in <module>
len(iter((1, 2, 3)))
TypeError: object of type 'tuple_iterator' has no len()
>>> len(iter([1, 2, 3]))
Traceback (most recent call last):
File "<pyshell#0>", line 1, in <module>
len(iter([1, 2, 3]))
TypeError: object of type 'list_iterator' has no len()
Upvotes: 1
Reputation: 7384
A file has no length:
>>> with open("test") as f:
... print(len(f))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: object of type '_io.TextIOWrapper' has no len()
Iterating through a file like that in open iterates over lines, i.e. chunks of text delimited by newline characters. To know how many lines there are, the file would have to be read entirely and then iterated through - depending on the size of the file this could take a long time or the computer could run out of RAM.
Upvotes: 5