Skip to content

Commit 61bd06c

Browse files
AlexEKorentrotterdylan
authored andcommitted
more itertools defined (google#15)
* added compress, cycle, dropwhile, from_iterable, ifilter, ifilterfalse, and takewhile in itertools * added itertools tests for cycle, dropwhile, from_iterable, ifilter, ifilterfalse, takewhile
1 parent c8ba5aa commit 61bd06c

File tree

3 files changed

+119
-5
lines changed

3 files changed

+119
-5
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
build
22
errors.err
33
*.swp
4+
*.pyc

lib/itertools.py

Lines changed: 44 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,19 +17,56 @@
1717
import _collections
1818
import sys
1919

20-
2120
def chain(*iterables):
2221
for it in iterables:
2322
for element in it:
2423
yield element
2524

25+
def compress(data, selectors):
26+
return (d for d,s in izip(data, selectors) if s)
2627

2728
def count(start=0, step=1):
2829
n = start
2930
while True:
3031
yield n
3132
n += step
3233

34+
def cycle(iterable):
35+
saved = []
36+
for element in iterable:
37+
yield element
38+
saved.append(element)
39+
while saved:
40+
for element in saved:
41+
yield element
42+
43+
def dropwhile(predicate, iterable):
44+
iterable = iter(iterable)
45+
for x in iterable:
46+
if not predicate(x):
47+
yield x
48+
break
49+
for x in iterable:
50+
yield x
51+
52+
def from_iterable(iterables):
53+
for it in iterables:
54+
for element in it:
55+
yield element
56+
57+
def ifilter(predicate, iterable):
58+
if predicate is None:
59+
predicate = bool
60+
for x in iterable:
61+
if predicate(x):
62+
yield x
63+
64+
def ifilterfalse(predicate, iterable):
65+
if predicate is None:
66+
predicate = bool
67+
for x in iterable:
68+
if not predicate(x):
69+
yield x
3370

3471
def imap(function, *iterables):
3572
iterables = map(iter, iterables)
@@ -40,7 +77,6 @@ def imap(function, *iterables):
4077
else:
4178
yield function(*args)
4279

43-
4480
def islice(iterable, *args):
4581
s = slice(*args)
4682
it = iter(xrange(s.start or 0, s.stop or sys.maxint, s.step or 1))
@@ -50,13 +86,11 @@ def islice(iterable, *args):
5086
yield element
5187
nexti = next(it)
5288

53-
5489
def izip(*iterables):
5590
iterators = map(iter, iterables)
5691
while iterators:
5792
yield tuple(map(next, iterators))
5893

59-
6094
def repeat(object, times=None):
6195
if times is None:
6296
while True:
@@ -65,11 +99,16 @@ def repeat(object, times=None):
6599
for i in xrange(times):
66100
yield object
67101

68-
69102
def starmap(function, iterable):
70103
for args in iterable:
71104
yield function(*args)
72105

106+
def takewhile(predicate, iterable):
107+
for x in iterable:
108+
if predicate(x):
109+
yield x
110+
else:
111+
break
73112

74113
def tee(iterable, n=2):
75114
it = iter(iterable)

lib/itertools_test.py

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,70 @@
1616

1717
import weetest
1818

19+
def TestCycle():
20+
want = []
21+
got = []
22+
for x in itertools.cycle(()):
23+
got.append(x)
24+
assert got == want, 'empty cycle yields no elements'
25+
26+
arg = (0, 1, 2)
27+
want = (0, 1, 2) * 10
28+
got = []
29+
limit = 10 * len(arg)
30+
counter = 0
31+
for x in itertools.cycle((0, 1, 2)):
32+
got.append(x)
33+
counter += 1
34+
if counter == limit:
35+
break
36+
assert tuple(got) == want, 'tuple(cycle%s) == %s, want %s' % (arg, tuple(got), want)
37+
38+
def TestDropwhile():
39+
r = range(10)
40+
cases = [
41+
((lambda x: x < 5, r), (5, 6, 7, 8, 9)),
42+
((lambda x: True, r), ()),
43+
((lambda x: False, r), tuple(r)),
44+
]
45+
for args, want in cases:
46+
got = tuple(itertools.dropwhile(*args))
47+
assert got == want, 'tuple(dropwhile%s) == %s, want %s' % (args, got, want)
48+
49+
def TestFromIterable():
50+
r = range(10)
51+
cases = [
52+
([r], tuple(r)),
53+
([r, r], tuple(r) + tuple(r)),
54+
([], ())
55+
]
56+
for args, want in cases:
57+
got = tuple(itertools.from_iterable(args))
58+
assert got == want, 'tuple(from_iterable%s) == %s, want %s' % (args, got, want)
59+
60+
def TestIFilter():
61+
r = range(10)
62+
cases = [
63+
((lambda x: x < 5, r), (0, 1, 2, 3, 4)),
64+
((lambda x: False, r), ()),
65+
((lambda x: True, r), tuple(r)),
66+
((None, r), (1, 2, 3, 4, 5, 6, 7, 8, 9))
67+
]
68+
for args, want in cases:
69+
got = tuple(itertools.ifilter(*args))
70+
assert got == want, 'tuple(ifilter%s) == %s, want %s' % (args, got, want)
71+
72+
def TestIFilterFalse():
73+
r = range(10)
74+
cases = [
75+
((lambda x: x < 5, r), (5, 6, 7, 8, 9)),
76+
((lambda x: False, r), tuple(r)),
77+
((lambda x: True, r), ()),
78+
((None, r), (0,))
79+
]
80+
for args, want in cases:
81+
got = tuple(itertools.ifilterfalse(*args))
82+
assert got == want, 'tuple(ifilterfalse%s) == %s, want %s' % (args, got, want)
1983

2084
def TestISlice():
2185
r = range(10)
@@ -28,6 +92,16 @@ def TestISlice():
2892
got = tuple(itertools.islice(*args))
2993
assert got == want, 'tuple(islice%s) == %s, want %s' % (args, got, want)
3094

95+
def TestTakewhile():
96+
r = range(10)
97+
cases = [
98+
((lambda x: x % 2 == 0, r), (0,)),
99+
((lambda x: True, r), tuple(r)),
100+
((lambda x: False, r), ())
101+
]
102+
for args, want in cases:
103+
got = tuple(itertools.takewhile(*args))
104+
assert got == want, 'tuple(takewhile%s) == %s, want %s' % (args, got, want)
31105

32106
if __name__ == '__main__':
33107
weetest.RunTests()

0 commit comments

Comments
 (0)