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 |
|