[ZODB-Dev] lazy BTreeItems
Tim Peters
tim at zope.com
Fri Dec 9 15:08:55 EST 2005
[Victor Safronovich]
> Hello zodb-dev!
>
> Is this a correct behaviour?
> >>> from BTrees.IIBTree import IIBTree
> >>> t = IIBTree(map(None,range(5),range(5)))
> >>> list(t.keys())
> [0, 1, 2, 3, 4]
> >>> k = t.keys()
> >>> list(k)
> [0, 1, 2, 3, 4]
> >>> del t[0]
> list(k)
> []
Nothing is defined about what an iterator "sees" after you mutate the object
from which the iterator was obtained. What you see consists of
implementation accidents then. More about this in the "Iteration and
Mutation" subsection of the BTrees docs at:
http://www.zope.org/Wikis/ZODB/FrontPage/guide/node6.html
... [skipping to next msg] ...
> >>> t = dict(map(None,range(5),range(5)))
> >>> for i in t.keys():
> if i in [1,3]:
> del t[i]
> print i
>
> 0
> 1
> 2
> 3
> 4
That's not the same thing. dict.keys() does not return a lazy iterator, it
returns a list. BTrees.keys() does not return a list, it returns a lazy
iterator. To make a dict example similar to the BTree example, use
dict.iterkeys(), or just iterate over the dict directly:
>>> five = range(5)
>>> t = dict(zip(five, five))
>>> t
{0: 0, 1: 1, 2: 2, 3: 3, 4: 4}
>>> for i in t: # same as "for i in t.iterkeys():"
... if i in [1, 3]:
... del t[i]
... print i
...
0
1
Traceback (most recent call last):
File "<stdin>", line 1, in ?
RuntimeError: dictionary changed size during iteration
> But this behaviour differs from dict objects, is this correct :)?
The .keys(), .values(), and .items() methods of BTrees are very different
from those methods on dicts in that the BTree methods return lazy iterators
but the dict methods return lists.
More information about the ZODB-Dev
mailing list