How does that compare to your experience with other iterators in Python?
Here’s what I get with a regular iterator:
>>> i = iter([1,2,3])
>>> bool(i)
True
>>> i = iter([])
>>> bool(i)
True
This is one thing that makes an iterator different from a container. An empty container is “falsy”. Virtually all other “objects” are “truthy”.
Edit: To be fair, it isn’t necessarily a bad idea. C++ has the concept of “empty ranges”, which test false when the range is exhausted. This method of stopping is handy in situations where Python’s exception-based approach (raise StopIteration when done) is too slow or bulky.
But there are situations where determining “emptiness” can be expensive. For example, an iterator backed by a network socket, and a buffer. If the buffer is empty, then the iterator might be “empty”; but that could change in a microsecond, as data arrives from across the network. In this case, Python’s iterator model, which is more general, looks to me like a better fit.
By now, there’s on the order of a billion lines of Python code that work under the above rules. Changing the rules now is probably not an option.
Came back to this, as I’ve hit this too. Going off the above linked Truth Value testing, the following
if rows:
# ... do something...
definitely is more Pythonic, compared to the suggested:
if len(rows):
# ... do something...
version. I haven’t really seen the latter used, though some go with the more explicit
if len(rows) > 0:
# ... do something...
version, which works here too, of course, just unnecessarily verbose.
Though maybe this departure from the Python list behaviour is somewhat expected, since the SearchIterator doesn’t seem to behave like an iterator either (more like a list in every other aspect), so I’m sure there are preconceptions and expectations that get broken
Still, if it “walks like list and quacks like list”, maybe it should be truthy like a list? But I can totally be missing something too.