[Zope-CVS] CVS: Packages/pypes/pypes - query.py:1.3
Casey Duncan
casey at zope.com
Fri Apr 2 22:50:25 EST 2004
Update of /cvs-repository/Packages/pypes/pypes
In directory cvs.zope.org:/tmp/cvs-serv24863
Modified Files:
query.py
Log Message:
Implement equi-join query primitive
=== Packages/pypes/pypes/query.py 1.2 => 1.3 ===
--- Packages/pypes/pypes/query.py:1.2 Wed Mar 31 00:00:52 2004
+++ Packages/pypes/pypes/query.py Fri Apr 2 22:50:23 2004
@@ -141,3 +141,48 @@
sortable = sortable[:limit]
# XXX We should be make this lazy
return [i for key, i in sortable]
+
+def equijoin(left_iter, left_expr, right_iter, right_expr):
+ """Join the values of the left_iter and right_iter iterables where the
+ value of left_expr equals the value of right_expr.
+
+ left_expr and right_expr are callables accepting the members of their
+ respective iterable input as a single argument which derive the values
+ to be compared.
+
+ Generate the resulting (left, right) tuple pairs where a join is made.
+ The resulting tuples are yielded in arbitrary order.
+
+ Complexity: O(N+M) where N=len(left), M=len(right)
+ """
+ try:
+ # See if we can measure the lengths and put the
+ # shorter sequence on the left so we use less memory
+ left_len = len(left_iter)
+ right_len = len(right_iter)
+ except TypeError:
+ pass # Can't measure length, may be iterator(s)
+ else:
+ if left_len > right_len:
+ tmp = left_len
+ left_len = right_len
+ right_len = tmp
+ tmp = left_expr
+ left_expr = right_expr
+ right_expr = tmp
+ left_by_val = {} # map of values => list of left matches
+ for obj in left_iter:
+ val = left_expr(obj)
+ try:
+ left_by_val[val].append(obj)
+ except KeyError:
+ left_by_val[val] = [obj]
+ for right in right_iter:
+ val = right_expr(right)
+ try:
+ left_matches = left_by_val[val]
+ except KeyError:
+ continue # No matching left objects
+ else:
+ for left in left_matches:
+ yield (left, right)
More information about the Zope-CVS
mailing list