Re[2]: [ZODB-Dev] lazy BTreeItems
Hello Dieter Maurer, Saturday, December 10, 2005, 12:32:35 AM, you wrote: DM l = range(10) DM for f in l: l.remove(f) DM l -- [1, 3, 5, 7, 9] DM Due to the much more complex BTree structures, the results DM of modifications during iteration might be even more surprising. I know about this Hello Tim Peters, Saturday, December 10, 2005, 1:08:55 AM, you wrote: TP The .keys(), .values(), and .items() methods of BTrees are very different TP from those methods on dicts in that the BTree methods return lazy iterators TP but the dict methods return lists. I undestand that i need keys|values|items cast to list, and from this new list get the new iterator. And a funny situation Starting debugger (the name app is bound to the top-level Zope object) from OFS.ObjectManager import ObjectManager from OFS.SimpleItem import SimpleItem m = ObjectManager() m._setObject('1',SimpleItem()) '1' m._setObject('2',SimpleItem()) '2' o_ids = m.objectIds() o_ids ['1', '2'] m._delObject('1') o_ids ['1', '2'] from Products.BTreeFolder2.BTreeFolder2 import BTreeFolder2 m = BTreeFolder2() m._setObject('1',SimpleItem()) '1' m._setObject('2',SimpleItem()) '2' o_ids = m.objectIds() o_ids OOBTreeItems object at 0x4015dca0 list(o_ids) ['1', '2'] m._delObject('1') list(o_ids) ['2'] I`ll want to migrate my large object containers from Folder to BTreeFolder2, but my code have many next places: for id in container.objectIds(): if some_condition: container._delObject(id) or container.manage_delObjects( container.objectIds() ) Be careful with migration of such type. -- Best regards, Victor Safronovich NauMen.NauDoc.SoftwareDeveloper http://www.naumen.ru ___ For more information about ZODB, see the ZODB Wiki: http://www.zope.org/Wikis/ZODB/ ZODB-Dev mailing list - ZODB-Dev@zope.org http://mail.zope.org/mailman/listinfo/zodb-dev
Re: [ZODB-Dev] lazy BTreeItems
Victor Safronovich wrote at 2005-12-9 12:05 +0500: 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) [] BUT i = iter(t.keys()) del t[1] list(i) [2, 3, 4] Things like these are to be expected! The BTrees methods keys, values and items are implemented as iterators. You should *NEVER* change the data structure being iterated over. If you do, funny things can happen -- not only with BTrees but with *ANY* iterator. E.g. l = range(10) for f in l: l.remove(f) l -- [1, 3, 5, 7, 9] Due to the much more complex BTree structures, the results of modifications during iteration might be even more surprising. -- Dieter ___ For more information about ZODB, see the ZODB Wiki: http://www.zope.org/Wikis/ZODB/ ZODB-Dev mailing list - ZODB-Dev@zope.org http://mail.zope.org/mailman/listinfo/zodb-dev
RE: [ZODB-Dev] lazy BTreeItems
[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. ___ For more information about ZODB, see the ZODB Wiki: http://www.zope.org/Wikis/ZODB/ ZODB-Dev mailing list - ZODB-Dev@zope.org http://mail.zope.org/mailman/listinfo/zodb-dev