web/lib/django/utils/itercompat.py
changeset 29 cc9b7e14412b
parent 0 0d40e90630ef
equal deleted inserted replaced
28:b758351d191f 29:cc9b7e14412b
     4 these implementations if necessary.
     4 these implementations if necessary.
     5 """
     5 """
     6 
     6 
     7 import itertools
     7 import itertools
     8 
     8 
     9 def compat_tee(iterable):
     9 # Fallback for Python 2.4, Python 2.5
       
    10 def product(*args, **kwds):
    10     """
    11     """
    11     Return two independent iterators from a single iterable.
    12     Taken from http://docs.python.org/library/itertools.html#itertools.product
       
    13     """
       
    14     # product('ABCD', 'xy') --> Ax Ay Bx By Cx Cy Dx Dy
       
    15     # product(range(2), repeat=3) --> 000 001 010 011 100 101 110 111
       
    16     pools = map(tuple, args) * kwds.get('repeat', 1)
       
    17     result = [[]]
       
    18     for pool in pools:
       
    19         result = [x+[y] for x in result for y in pool]
       
    20     for prod in result:
       
    21         yield tuple(prod)
    12 
    22 
    13     Based on http://www.python.org/doc/2.3.5/lib/itertools-example.html
    23 if hasattr(itertools, 'product'):
    14     """
    24     product = itertools.product
    15     # Note: Using a dictionary and a list as the default arguments here is
       
    16     # deliberate and safe in this instance.
       
    17     def gen(next, data={}, cnt=[0]):
       
    18         dpop = data.pop
       
    19         for i in itertools.count():
       
    20             if i == cnt[0]:
       
    21                 item = data[i] = next()
       
    22                 cnt[0] += 1
       
    23             else:
       
    24                 item = dpop(i)
       
    25             yield item
       
    26     next = iter(iterable).next
       
    27     return gen(next), gen(next)
       
    28 
       
    29 def groupby(iterable, keyfunc=None):
       
    30     """
       
    31     Taken from http://docs.python.org/lib/itertools-functions.html
       
    32     """
       
    33     if keyfunc is None:
       
    34         keyfunc = lambda x:x
       
    35     iterable = iter(iterable)
       
    36     l = [iterable.next()]
       
    37     lastkey = keyfunc(l[0])
       
    38     for item in iterable:
       
    39         key = keyfunc(item)
       
    40         if key != lastkey:
       
    41             yield lastkey, l
       
    42             lastkey = key
       
    43             l = [item]
       
    44         else:
       
    45             l.append(item)
       
    46     yield lastkey, l
       
    47 
       
    48 # Not really in itertools, since it's a builtin in Python 2.4 and later, but it
       
    49 # does operate as an iterator.
       
    50 def reversed(data):
       
    51     for index in xrange(len(data)-1, -1, -1):
       
    52         yield data[index]
       
    53 
       
    54 if hasattr(itertools, 'tee'):
       
    55     tee = itertools.tee
       
    56 else:
       
    57     tee = compat_tee
       
    58 if hasattr(itertools, 'groupby'):
       
    59     groupby = itertools.groupby
       
    60 
    25 
    61 def is_iterable(x):
    26 def is_iterable(x):
    62     "A implementation independent way of checking for iterables"
    27     "A implementation independent way of checking for iterables"
    63     try:
    28     try:
    64         iter(x)
    29         iter(x)
    65     except TypeError:
    30     except TypeError:
    66         return False
    31         return False
    67     else:
    32     else:
    68         return True
    33         return True
    69 
    34 
    70 def sorted(in_value):
    35 def all(iterable):
    71     "A naive implementation of sorted"
    36     for item in iterable:
    72     out_value = in_value[:]
    37         if not item:
    73     out_value.sort()
    38             return False
    74     return out_value
    39     return True
    75