12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#!/usr/bin/env python 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#coding:utf-8 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)# Author: Mozman 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)# Purpose: treemixin provides top level functions for binary trees 52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)# Created: 03.05.2010 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)# Copyright (c) 2010-2013 by Manfred Moitzi 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)# License: MIT License 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)from __future__ import absolute_import 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)from .walker import Walker 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)from .treeslice import TreeSlice 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class TreeMixin(object): 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """ 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Abstract-Base-Class for the pure Python Trees: BinaryTree, AVLTree and RBTree 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Mixin-Class for the Cython based Trees: FastBinaryTree, FastAVLTree, FastRBTree 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) The TreeMixin Class 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) =================== 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) T has to implement following properties 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) --------------------------------------- 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) count -- get node count 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) T has to implement following methods 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ------------------------------------ 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) get_walker(...) 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) get a tree walker object, provides methods to traverse the tree see walker.py 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) insert(...) 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) insert(key, value) <==> T[key] = value, insert key into T 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) remove(...) 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) remove(key) <==> del T[key], remove key from T 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) clear(...) 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) T.clear() -> None. Remove all items from T. 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Methods defined here 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) -------------------- 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * __contains__(k) -> True if T has a key k, else False, O(log(n)) 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * __delitem__(y) <==> del T[y], del T[s:e], O(log(n)) 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * __getitem__(y) <==> T[y], T[s:e], O(log(n)) 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * __iter__() <==> iter(T) 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * __len__() <==> len(T), O(1) 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * __max__() <==> max(T), get max item (k,v) of T, O(log(n)) 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * __min__() <==> min(T), get min item (k,v) of T, O(log(n)) 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * __and__(other) <==> T & other, intersection 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * __or__(other) <==> T | other, union 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * __sub__(other) <==> T - other, difference 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * __xor__(other) <==> T ^ other, symmetric_difference 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * __repr__() <==> repr(T) 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * __setitem__(k, v) <==> T[k] = v, O(log(n)) 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * clear() -> None, Remove all items from T, , O(n) 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * copy() -> a shallow copy of T, O(n*log(n)) 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * discard(k) -> None, remove k from T, if k is present, O(log(n)) 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * get(k[,d]) -> T[k] if k in T, else d, O(log(n)) 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * is_empty() -> True if len(T) == 0, O(1) 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * items([reverse]) -> generator for (k, v) items of T, O(n) 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * keys([reverse]) -> generator for keys of T, O(n) 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * values([reverse]) -> generator for values of T, O(n) 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * pop(k[,d]) -> v, remove specified key and return the corresponding value, O(log(n)) 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * popitem() -> (k, v), remove and return some (key, value) pair as a 2-tuple, O(log(n)) 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * setdefault(k[,d]) -> T.get(k, d), also set T[k]=d if k not in T, O(log(n)) 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * update(E) -> None. Update T from dict/iterable E, O(E*log(n)) 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * foreach(f, [order]) -> visit all nodes of tree and call f(k, v) for each node, O(n) 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) slicing by keys 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * itemslice(s, e) -> generator for (k, v) items of T for s <= key < e, O(n) 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * keyslice(s, e) -> generator for keys of T for s <= key < e, O(n) 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * valueslice(s, e) -> generator for values of T for s <= key < e, O(n) 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * T[s:e] -> TreeSlice object, with keys in range s <= key < e, O(n) 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * del T[s:e] -> remove items by key slicing, for s <= key < e, O(n) 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if 's' is None or T[:e] TreeSlice/iterator starts with value of min_key() 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if 'e' is None or T[s:] TreeSlice/iterator ends with value of max_key() 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) T[:] is a TreeSlice which represents the whole tree. 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TreeSlice is a tree wrapper with range check, and contains no references 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) to objects, deleting objects in the associated tree also deletes the object 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) in the TreeSlice. 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * TreeSlice[k] -> get value for key k, raises KeyError if k not exists in range s:e 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * TreeSlice[s1:e1] -> TreeSlice object, with keys in range s1 <= key < e1 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * new lower bound is max(s, s1) 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * new upper bound is min(e, e1) 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TreeSlice methods: 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * items() -> generator for (k, v) items of T, O(n) 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * keys() -> generator for keys of T, O(n) 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * values() -> generator for values of T, O(n) 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * __iter__ <==> keys() 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * __repr__ <==> repr(T) 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * __contains__(key)-> True if TreeSlice has a key k, else False, O(log(n)) 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) prev/succ operations 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * prev_item(key) -> get (k, v) pair, where k is predecessor to key, O(log(n)) 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * prev_key(key) -> k, get the predecessor of key, O(log(n)) 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * succ_item(key) -> get (k,v) pair as a 2-tuple, where k is successor to key, O(log(n)) 1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * succ_key(key) -> k, get the successor of key, O(log(n)) 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * floor_item(key) -> get (k, v) pair, where k is the greatest key less than or equal to key, O(log(n)) 1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * floor_key(key) -> k, get the greatest key less than or equal to key, O(log(n)) 1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * ceiling_item(key) -> get (k, v) pair, where k is the smallest key greater than or equal to key, O(log(n)) 1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * ceiling_key(key) -> k, get the smallest key greater than or equal to key, O(log(n)) 1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Heap methods 1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * max_item() -> get largest (key, value) pair of T, O(log(n)) 1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * max_key() -> get largest key of T, O(log(n)) 1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * min_item() -> get smallest (key, value) pair of T, O(log(n)) 1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * min_key() -> get smallest key of T, O(log(n)) 1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * pop_min() -> (k, v), remove item with minimum key, O(log(n)) 1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * pop_max() -> (k, v), remove item with maximum key, O(log(n)) 1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * nlargest(i[,pop]) -> get list of i largest items (k, v), O(i*log(n)) 1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * nsmallest(i[,pop]) -> get list of i smallest items (k, v), O(i*log(n)) 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Set methods (using frozenset) 1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * intersection(t1, t2, ...) -> Tree with keys *common* to all trees 1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * union(t1, t2, ...) -> Tree with keys from *either* trees 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * difference(t1, t2, ...) -> Tree with keys in T but not any of t1, t2, ... 1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * symmetric_difference(t1) -> Tree with keys in either T and t1 but not both 1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * issubset(S) -> True if every element in T is in S 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * issuperset(S) -> True if every element in S is in T 1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * isdisjoint(S) -> True if T has a null intersection with S 1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Classmethods 1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * fromkeys(S[,v]) -> New tree with keys from S and values equal to v. 1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """ 1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def get_walker(self): 1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Walker(self) 1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def __repr__(self): 1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """ x.__repr__(...) <==> repr(x) """ 1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tpl = "%s({%s})" % (self.__class__.__name__, '%s') 1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return tpl % ", ".join( ("%r: %r" % item for item in self.items()) ) 1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def copy(self): 1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """ T.copy() -> get a shallow copy of T. """ 1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tree = self.__class__() 1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) self.foreach(tree.insert, order=-1) 1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return tree 1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) __copy__ = copy 1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def __contains__(self, key): 1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """ k in T -> True if T has a key k, else False """ 1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) try: 1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) self.get_value(key) 1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return True 1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) except KeyError: 1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return False 1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def __len__(self): 1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """ x.__len__() <==> len(x) """ 1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return self.count 1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def __min__(self): 1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """ x.__min__() <==> min(x) """ 1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return self.min_item() 1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def __max__(self): 1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """ x.__max__() <==> max(x) """ 1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return self.max_item() 1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def __and__(self, other): 1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """ x.__and__(other) <==> self & other """ 1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return self.intersection(other) 1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def __or__(self, other): 1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """ x.__or__(other) <==> self | other """ 1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return self.union(other) 1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def __sub__(self, other): 1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """ x.__sub__(other) <==> self - other """ 1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return self.difference(other) 1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def __xor__(self, other): 1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """ x.__xor__(other) <==> self ^ other """ 1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return self.symmetric_difference(other) 1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def discard(self, key): 1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """ x.discard(k) -> None, remove k from T, if k is present """ 1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) try: 1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) self.remove(key) 1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) except KeyError: 1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) pass 1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def __del__(self): 1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) self.clear() 2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def is_empty(self): 2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """ x.is_empty() -> False if T contains any items else True""" 2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return self.count == 0 2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def keys(self, reverse=False): 2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """ T.iterkeys([reverse]) -> an iterator over the keys of T, in ascending 2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) order if reverse is True, iterate in descending order, reverse defaults 2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) to False 2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """ 2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return ( item[0] for item in self.items(reverse) ) 2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) __iter__ = keys 2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def __reversed__(self): 2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return self.keys(reverse=True) 2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def values(self, reverse=False): 2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """ T.values([reverse]) -> an iterator over the values of T, in ascending order 2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if reverse is True, iterate in descending order, reverse defaults to False 2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """ 2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return ( item[1] for item in self.items(reverse) ) 2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def items(self, reverse=False): 2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """ T.items([reverse]) -> an iterator over the (key, value) items of T, 2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) in ascending order if reverse is True, iterate in descending order, 2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) reverse defaults to False 2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """ 2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if self.is_empty(): 2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return [] 2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def default_iterator(node): 2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) direction = 1 if reverse else 0 2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) other = 1 - direction 2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) go_down = True 2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) while True: 2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if node.has_child(direction) and go_down: 2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) node.push() 2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) node.down(direction) 2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else: 2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) yield node.item 2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if node.has_child(other): 2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) node.down(other) 2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) go_down = True 2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else: 2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if node.stack_is_empty(): 2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return # all done 2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) node.pop() 2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) go_down = False 2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) treewalker = self.get_walker() 2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) try: # specialized iterators 2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if reverse: 2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return treewalker.iter_items_backward() 2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else: 2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return treewalker.iter_items_forward() 2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) except AttributeError: 2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return default_iterator(treewalker) 2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def __getitem__(self, key): 2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """ x.__getitem__(y) <==> x[y] """ 2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if isinstance(key, slice): 2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return TreeSlice(self, key.start, key.stop) 2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else: 2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return self.get_value(key) 2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def __setitem__(self, key, value): 2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """ x.__setitem__(i, y) <==> x[i]=y """ 2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if isinstance(key, slice): 2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) raise ValueError('setslice is not supported') 2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) self.insert(key, value) 2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def __delitem__(self, key): 2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """ x.__delitem__(y) <==> del x[y] """ 2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if isinstance(key, slice): 2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) self.delitems(self.keyslice(key.start, key.stop)) 2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else: 2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) self.remove(key) 2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def delitems(self, keys): 2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """ T.delitems(keys) -> remove all items by keys 2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """ 2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # convert generator to a set, because the content of the 2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # tree will be modified! 2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for key in frozenset(keys): 2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) self.remove(key) 2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def keyslice(self, startkey, endkey): 2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """ T.keyslice(startkey, endkey) -> key iterator: 2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) startkey <= key < endkey. 2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """ 2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return ( item[0] for item in self.itemslice(startkey, endkey) ) 2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def itemslice(self, startkey, endkey): 2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """ T.itemslice(s, e) -> item iterator: s <= key < e. 2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if s is None: start with min element -> T[:e] 2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if e is None: end with max element -> T[s:] 2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) T[:] -> all items 2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """ 3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if self.is_empty(): 3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return 3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if startkey is None: 3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # no lower bound 3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) can_go_left = lambda: node.has_left() and visit_left 3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else: 3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # don't visit subtrees without keys in search range 3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) can_go_left = lambda: node.key > startkey and node.has_left() and visit_left 3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if endkey is None: 3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # no upper bound 3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) can_go_right = lambda: node.has_right() 3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else: 3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # don't visit subtrees without keys in search range 3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) can_go_right = lambda: node.key < endkey and node.has_right() 3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (startkey, endkey) == (None, None): 3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) key_in_range = lambda: True 3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) elif startkey is None: 3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) key_in_range = lambda: node.key < endkey 3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) elif endkey is None: 3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) key_in_range = lambda: node.key >= startkey 3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else: 3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) key_in_range = lambda: startkey <= node.key < endkey 3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) node = self.get_walker() 3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) visit_left = True 3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) while True: 3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if can_go_left(): 3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) node.push() 3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) node.go_left() 3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else: 3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if key_in_range(): 3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) yield node.item 3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if can_go_right(): 3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) node.go_right() 3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) visit_left = True 3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else: 3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if node.stack_is_empty(): 3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return 3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) node.pop() 3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # left side is already done 3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) visit_left = False 3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def valueslice(self, startkey, endkey): 3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """ T.valueslice(startkey, endkey) -> value iterator: 3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) startkey <= key < endkey. 3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """ 3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return ( item[1] for item in self.itemslice(startkey, endkey) ) 3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def get_value(self, key): 3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) node = self.root 3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) while node is not None: 3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if key == node.key: 3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return node.value 3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) elif key < node.key: 3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) node = node.left 3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else: 3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) node = node.right 3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) raise KeyError(str(key)) 3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def __getstate__(self): 3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return dict(self.items()) 3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def __setstate__(self, state): 3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # note for myself: this is called like __init__, so don't use clear() 3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # to remove existing data! 3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) self._root = None 3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) self._count = 0 3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) self.update(state) 3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def setdefault(self, key, default=None): 3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """ T.setdefault(k[,d]) -> T.get(k,d), also set T[k]=d if k not in T """ 3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) try: 3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return self.get_value(key) 3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) except KeyError: 3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) self.insert(key, default) 3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return default 3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def update(self, *args): 3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """ T.update(E) -> None. Update T from E : for (k, v) in E: T[k] = v """ 3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for items in args: 3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) try: 3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) generator = items.items() 3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) except AttributeError: 3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) generator = iter(items) 3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for key, value in generator: 3892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) self.insert(key, value) 3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) @classmethod 3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def fromkeys(cls, iterable, value=None): 3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """ T.fromkeys(S[,v]) -> New tree with keys from S and values equal to v. 3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) v defaults to None. 3962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """ 3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tree = cls() 3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for key in iterable: 3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tree.insert(key, value) 4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return tree 4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def get(self, key, default=None): 4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """ T.get(k[,d]) -> T[k] if k in T, else d. d defaults to None. """ 4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) try: 4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return self.get_value(key) 4062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) except KeyError: 4072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return default 4082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def pop(self, key, *args): 4102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """ T.pop(k[,d]) -> v, remove specified key and return the corresponding value 4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) If key is not found, d is returned if given, otherwise KeyError is raised 4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """ 4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if len(args) > 1: 4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) raise TypeError("pop expected at most 2 arguments, got %d" % (1 + len(args))) 4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) try: 4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) value = self.get_value(key) 4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) self.remove(key) 4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return value 4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) except KeyError: 4202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if len(args) == 0: 4212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) raise 4222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else: 4232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return args[0] 4242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def popitem(self): 4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """ T.popitem() -> (k, v), remove and return some (key, value) pair as a 4272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2-tuple; but raise KeyError if T is empty 4282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """ 4292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if self.is_empty(): 4302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) raise KeyError("popitem(): tree is empty") 4312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) walker = self.get_walker() 4322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) walker.goto_leaf() 4332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) result = walker.item 4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) self.remove(walker.key) 4352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return result 4362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def foreach(self, func, order=0): 4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """ Visit all tree nodes and process key, value. 4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) parm func: function(key, value) 4412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) param int order: inorder = 0, preorder = -1, postorder = +1 4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """ 4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def _traverse(): 4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if order == -1: 4462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) func(node.key, node.value) 4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if node.has_left(): 4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) node.push() 4492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) node.go_left() 4502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) _traverse() 4512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) node.pop() 4522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if order == 0: 4532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) func(node.key, node.value) 4542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if node.has_right(): 4552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) node.push() 4562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) node.go_right() 4572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) _traverse() 4582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) node.pop() 4592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if order == +1: 4602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) func(node.key, node.value) 4612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) node = self.get_walker() 4632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) _traverse() 4642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def min_item(self): 4662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """ Get item with min key of tree, raises ValueError if tree is empty. """ 4672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if self.count == 0: 4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) raise ValueError("Tree is empty") 4692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) node = self._root 4702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) while node.left is not None: 4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) node = node.left 4722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return (node.key, node.value) 4732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def pop_min(self): 4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """ T.pop_min() -> (k, v), remove item with minimum key, raise ValueError 4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if T is empty. 4772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """ 4782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) item = self.min_item() 4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) self.remove(item[0]) 4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return item 4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def min_key(self): 4832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """ Get min key of tree, raises ValueError if tree is empty. """ 4842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) key, value = self.min_item() 4852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return key 4862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def prev_item(self, key): 4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """ Get predecessor (k,v) pair of key, raises KeyError if key is min key 4892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) or key does not exist. 4902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """ 4912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if self.count == 0: 4922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) raise KeyError("Tree is empty") 4932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) walker = self.get_walker() 4942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return walker.prev_item(key) 4952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def succ_item(self, key): 4972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """ Get successor (k,v) pair of key, raises KeyError if key is max key 4982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) or key does not exist. 4992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """ 5002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if self.count == 0: 5012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) raise KeyError("Tree is empty") 5022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) walker = self.get_walker() 5032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return walker.succ_item(key) 5042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def prev_key(self, key): 5062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """ Get predecessor to key, raises KeyError if key is min key 5072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) or key does not exist. 5082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """ 5092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) key, value = self.prev_item(key) 5102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return key 5112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def succ_key(self, key): 5132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """ Get successor to key, raises KeyError if key is max key 5142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) or key does not exist. 5152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """ 5162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) key, value = self.succ_item(key) 5172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return key 5182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def floor_item(self, key): 5202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """ Get the element (k,v) pair associated with the greatest key less 5212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) than or equal to the given key, raises KeyError if there is no such key. 5222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """ 5232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if self.count == 0: 5242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) raise KeyError("Tree is empty") 5252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) walker = self.get_walker() 5262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return walker.floor_item(key) 5272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def floor_key(self, key): 5292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """ Get the greatest key less than or equal to the given key, raises 5302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) KeyError if there is no such key. 5312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """ 5322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) key, value = self.floor_item(key) 5332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return key 5342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def ceiling_item(self, key): 5362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """ Get the element (k,v) pair associated with the smallest key greater 5372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) than or equal to the given key, raises KeyError if there is no such key. 5382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """ 5392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if self.count == 0: 5402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) raise KeyError("Tree is empty") 5412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) walker = self.get_walker() 5422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return walker.ceiling_item(key) 5432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def ceiling_key(self, key): 5452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """ Get the smallest key greater than or equal to the given key, raises 5462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) KeyError if there is no such key. 5472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """ 5482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) key, value = self.ceiling_item(key) 5492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return key 5502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def max_item(self): 5522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """ Get item with max key of tree, raises ValueError if tree is empty. """ 5532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if self.count == 0: 5542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) raise ValueError("Tree is empty") 5552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) node = self._root 5562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) while node.right is not None: 5572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) node = node.right 5582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return (node.key, node.value) 5592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def pop_max(self): 5612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """ T.pop_max() -> (k, v), remove item with maximum key, raise ValueError 5622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if T is empty. 5632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """ 5642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) item = self.max_item() 5652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) self.remove(item[0]) 5662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return item 5672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def max_key(self): 5692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """ Get max key of tree, raises ValueError if tree is empty. """ 5702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) key, value = self.max_item() 5712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return key 5722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def nsmallest(self, n, pop=False): 5742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """ T.nsmallest(n) -> get list of n smallest items (k, v). 5752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) If pop is True, remove items from T. 5762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """ 5772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if pop: 5782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return [self.pop_min() for _ in range(min(len(self), n))] 5792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else: 5802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) items = self.items() 5812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return [ next(items) for _ in range(min(len(self), n)) ] 5822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def nlargest(self, n, pop=False): 5842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """ T.nlargest(n) -> get list of n largest items (k, v). 5852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) If pop is True remove items from T. 5862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """ 5872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if pop: 5882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return [self.pop_max() for _ in range(min(len(self), n))] 5892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else: 5902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) items = self.items(reverse=True) 5912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return [ next(items) for _ in range(min(len(self), n)) ] 5922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def intersection(self, *trees): 5942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """ x.intersection(t1, t2, ...) -> Tree, with keys *common* to all trees 5952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """ 5962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) thiskeys = frozenset(self.keys()) 5972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) sets = _build_sets(trees) 5982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) rkeys = thiskeys.intersection(*sets) 5992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return self.__class__( ((key, self.get(key)) for key in rkeys) ) 6002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def union(self, *trees): 6022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """ x.union(t1, t2, ...) -> Tree with keys from *either* trees 6032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """ 6042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) thiskeys = frozenset(self.keys()) 6052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) rkeys = thiskeys.union(*_build_sets(trees)) 6062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return self.__class__( ((key, self.get(key)) for key in rkeys) ) 6072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def difference(self, *trees): 6092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """ x.difference(t1, t2, ...) -> Tree with keys in T but not any of t1, 6102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) t2, ... 6112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """ 6122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) thiskeys = frozenset(self.keys()) 6132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) rkeys = thiskeys.difference(*_build_sets(trees)) 6142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return self.__class__( ((key, self.get(key)) for key in rkeys) ) 6152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def symmetric_difference(self, tree): 6172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """ x.symmetric_difference(t1) -> Tree with keys in either T and t1 but 6182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) not both 6192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """ 6202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) thiskeys = frozenset(self.keys()) 6212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) rkeys = thiskeys.symmetric_difference(frozenset(tree.keys())) 6222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return self.__class__( ((key, self.get(key)) for key in rkeys) ) 6232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def issubset(self, tree): 6252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """ x.issubset(tree) -> True if every element in x is in tree """ 6262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) thiskeys = frozenset(self.keys()) 6272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return thiskeys.issubset(frozenset(tree.keys())) 6282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def issuperset(self, tree): 6302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """ x.issubset(tree) -> True if every element in tree is in x """ 6312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) thiskeys = frozenset(self.keys()) 6322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return thiskeys.issuperset(frozenset(tree.keys())) 6332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def isdisjoint(self, tree): 6352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """ x.isdisjoint(S) -> True if x has a null intersection with tree """ 6362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) thiskeys = frozenset(self.keys()) 6372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return thiskeys.isdisjoint(frozenset(tree.keys())) 6382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)def _build_sets(trees): 6412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return [ frozenset(tree.keys()) for tree in trees ] 6422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 643