diff -r 57b4279d8c4e -r 03e267d67478 app/django/utils/itercompat.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/app/django/utils/itercompat.py Fri Jul 18 18:22:23 2008 +0000 @@ -0,0 +1,69 @@ +""" +Providing iterator functions that are not in all version of Python we support. +Where possible, we try to use the system-native version and only fall back to +these implementations if necessary. +""" + +import itertools + +def compat_tee(iterable): + """ + Return two independent iterators from a single iterable. + + Based on http://www.python.org/doc/2.3.5/lib/itertools-example.html + """ + # Note: Using a dictionary and a list as the default arguments here is + # deliberate and safe in this instance. + def gen(next, data={}, cnt=[0]): + dpop = data.pop + for i in itertools.count(): + if i == cnt[0]: + item = data[i] = next() + cnt[0] += 1 + else: + item = dpop(i) + yield item + next = iter(iterable).next + return gen(next), gen(next) + +def groupby(iterable, keyfunc=None): + """ + Taken from http://docs.python.org/lib/itertools-functions.html + """ + if keyfunc is None: + keyfunc = lambda x:x + iterable = iter(iterable) + l = [iterable.next()] + lastkey = keyfunc(l[0]) + for item in iterable: + key = keyfunc(item) + if key != lastkey: + yield lastkey, l + lastkey = key + l = [item] + else: + l.append(item) + yield lastkey, l + +# Not really in itertools, since it's a builtin in Python 2.4 and later, but it +# does operate as an iterator. +def reversed(data): + for index in xrange(len(data)-1, -1, -1): + yield data[index] + +if hasattr(itertools, 'tee'): + tee = itertools.tee +else: + tee = compat_tee +if hasattr(itertools, 'groupby'): + groupby = itertools.groupby + +def is_iterable(x): + "A implementation independent way of checking for iterables" + try: + iter(x) + except TypeError: + return False + else: + return True +