From b04ffaf9056b016a4b3092538a7de125905eee49 Mon Sep 17 00:00:00 2001 From: William Song <30965609+Freakwill@users.noreply.github.com> Date: Sat, 20 Jan 2018 10:18:15 +0800 Subject: [PATCH 1/5] Update itertoolz.py add some new functions --- toolz/itertoolz.py | 49 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/toolz/itertoolz.py b/toolz/itertoolz.py index a25eea3c..8280fb47 100644 --- a/toolz/itertoolz.py +++ b/toolz/itertoolz.py @@ -980,3 +980,52 @@ def random_sample(prob, seq, random_state=None): if not hasattr(random_state, 'random'): random_state = Random(random_state) return filter(lambda _: random_state.random() < prob, seq) + + +def power(iterable, hook=set): + # the power set of iterable + return (hook(a) for a in toolz.concat(itertools.combinations(iterable, r) for r in range(len(iterable)+1))) + + + +def quotient(lst, key=None, rel=lambda x, y: x==y): + '''rel is an equivalent relation + return a partition of X, X/rel + also see groupby in toolz + Remark: It is named partition at first, but conflits with the original one. + quotient is another acceptable name. +''' + if lst==[]: + return lst + elif len(lst)==1: + return [lst] + if key: + rel = lambda x, y: key(x)==key(y) + #~ if rel: key = lambda x: {a for a in lst if rel(x, a)} + p = [[lst[0]]] + for a in lst[1:]: + for cls in p: + if rel(a, cls[0]): + cls.append(a) + break + else: + p.append([a]) + return p + +def sortby(lst, key=None, rel=lambda x, y: x==y): + # see quotient + return concat(quotient(lst, key, rel)) + +def repeatby(lst, nums): + '''example: +>>> repeatby(['w','r','y'],[3,2,1,2]) +['w', 'w', 'w', 'r', 'r', 'y', 'w', 'w'] +''' + new = [] + l = len(lst) + for k, n in enumerate(nums): + if l>k: + new.extend([lst[k]]*n) + else: + new.extend([lst[k%l]]*n) + return new From a50c03179ffecd6f0d4d91d6133a8acaeabd2eb7 Mon Sep 17 00:00:00 2001 From: William Song <30965609+Freakwill@users.noreply.github.com> Date: Sat, 20 Jan 2018 16:42:27 +0800 Subject: [PATCH 2/5] Update test_itertoolz.py --- toolz/tests/test_itertoolz.py | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/toolz/tests/test_itertoolz.py b/toolz/tests/test_itertoolz.py index 93aa856d..14161f09 100644 --- a/toolz/tests/test_itertoolz.py +++ b/toolz/tests/test_itertoolz.py @@ -524,3 +524,26 @@ def test_random_sample(): assert mk_rsample(b"a") == mk_rsample(u"a") assert raises(TypeError, lambda: mk_rsample([])) + + + +def test_power(): + assert set(power([1])) == {{1}, set()} + + +def test_quotient(): + S = [1,2,3,4,5,6] + Q = quotient(S, rel=lambda x, y: (x-y) % 3 ==0) + assert Q == [[1, 4], [2, 5], [3, 6]] + Q1 = quotient(S, key=lambda x: x % 3) + assert Q1 == [[1, 4], [2, 5], [3, 6]] + + assert quotient([], rel=lambda x:1) == [] + +def test_sortby(): + S = [1,2,3,4,5,6] + Q = sortby(S, rel=lambda x, y: (x-y) % 3 ==0) + assert Q == [1, 4, 2, 5, 3, 6] + +def test_repeatby(): + assert repeatby(['w','r','y'], [3,2,1,2]) == ['w', 'w', 'w', 'r', 'r', 'y', 'w', 'w'] From 2314ede2aa4699d3a2ed4beaf4aeb505684224c9 Mon Sep 17 00:00:00 2001 From: William Song <30965609+Freakwill@users.noreply.github.com> Date: Sat, 20 Jan 2018 16:53:48 +0800 Subject: [PATCH 3/5] Update itertoolz.py correct the tuple of __all__ --- toolz/itertoolz.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/toolz/itertoolz.py b/toolz/itertoolz.py index 8280fb47..9d26847a 100644 --- a/toolz/itertoolz.py +++ b/toolz/itertoolz.py @@ -14,7 +14,7 @@ 'first', 'second', 'nth', 'last', 'get', 'concat', 'concatv', 'mapcat', 'cons', 'interpose', 'frequencies', 'reduceby', 'iterate', 'sliding_window', 'partition', 'partition_all', 'count', 'pluck', - 'join', 'tail', 'diff', 'topk', 'peek', 'random_sample') + 'join', 'tail', 'diff', 'topk', 'peek', 'random_sample', 'power', 'quotient', 'sortby', 'repeatby') def remove(predicate, seq): From d23d2f0d7f82b1c4bd1b9697e1ac975853cb42c4 Mon Sep 17 00:00:00 2001 From: William Song <30965609+Freakwill@users.noreply.github.com> Date: Sat, 20 Jan 2018 22:11:23 +0800 Subject: [PATCH 4/5] Update test_itertoolz.py import the functions --- toolz/tests/test_itertoolz.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/toolz/tests/test_itertoolz.py b/toolz/tests/test_itertoolz.py index 14161f09..65c1192b 100644 --- a/toolz/tests/test_itertoolz.py +++ b/toolz/tests/test_itertoolz.py @@ -13,7 +13,7 @@ reduceby, iterate, accumulate, sliding_window, count, partition, partition_all, take_nth, pluck, join, - diff, topk, peek, random_sample) + diff, topk, peek, random_sample, power, quotient, sortby, repeatby) from toolz.compatibility import range, filter from operator import add, mul From 1c4da0d6286847f30c3b8480133440d74c4f0c58 Mon Sep 17 00:00:00 2001 From: William Song <30965609+Freakwill@users.noreply.github.com> Date: Sun, 21 Jan 2018 10:47:40 +0800 Subject: [PATCH 5/5] Update itertoolz.py --- toolz/itertoolz.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/toolz/itertoolz.py b/toolz/itertoolz.py index 9d26847a..666166eb 100644 --- a/toolz/itertoolz.py +++ b/toolz/itertoolz.py @@ -984,7 +984,7 @@ def random_sample(prob, seq, random_state=None): def power(iterable, hook=set): # the power set of iterable - return (hook(a) for a in toolz.concat(itertools.combinations(iterable, r) for r in range(len(iterable)+1))) + return (hook(a) for a in concat(itertools.combinations(iterable, r) for r in range(len(iterable)+1)))