list() coercion

Alan Kennedy alanmk at hotmail.com
Thu Jul 17 16:48:37 CEST 2003


Ian Bicking wrote:

>>> However, list() seems to call the object's
>>> __len__,
>>>
>>> Is there a way I can keep this from happening?

Greg Ewing:

>> Give your object an __iter__ method that returns
>> itself.

Ian Bicking wrote:

> I'm not clear on how that will help...?
> 
> It already does have an __iter__ method, but it returns a separate
> iterator.

Just to be explicitly clear

1. You're retrieving record sets from a database.
2. You want to build a list from the database results, one list entry
for each result row.
3. You don't want to have the list preallocated (thus requiring
invocation of __len__()), because the time saving is not worth it
(compared to the cost of the SQL count() operation), since you're
going to be iterating over the record set anyway.

Therefore, use an iterator to build up the list. This will not call
__len__(). Instead, the list will continually be appended to, until
the iterator raise StopIteration. The list may be re-allocated
multiple times, as the number of records retrieved exceeds the
allocation unit size of lists. But this will likely still be lower
cost than your SQL count().

The object returned from the __iter__() method should have a .next()
method which returns the next row in your result set. So if you have
implemented a .next() on your result set object, define your
__.iter__() method as follows

class ResultSet:

    def next(self):
        "Pseudocode"
        result = databasecursor.fetchone()
        if result:
            return result
        else:
            raise StopIteration

    def __iter__(self):
        return self

Have I understood the problem correctly?

-- 
alan kennedy
-----------------------------------------------------
check http headers here: http://xhaus.com/headers
email alan:              http://xhaus.com/mailto/alan




More information about the Python-list mailing list