-
Notifications
You must be signed in to change notification settings - Fork 49
/
Copy pathfunctional.py
87 lines (62 loc) · 1.76 KB
/
functional.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
from __future__ import absolute_import, print_function, unicode_literals
import inspect
from functools import reduce
from itertools import chain, islice
from wolframclient.utils import six
if six.PY2:
def map(f, iterable):
return (f(e) for e in iterable)
else:
map = map
def first(iterable, default=None):
try:
return next(iter(iterable))
except StopIteration:
return default
def last(iterable, default=None):
try:
return iterable[-1]
except IndexError:
return default
def identity(x):
return x
def composition(*functions):
return reduce(
lambda f, g: lambda *args, **kw: f(g(*args, **kw)), reversed(functions or (identity,))
)
def is_iterable(obj, exclude_list=six.string_types):
if isinstance(obj, exclude_list):
return False
return not inspect.isclass(obj) and hasattr(obj, "__iter__")
def to_iterable(obj, exclude_list=six.string_types):
if isinstance(obj, exclude_list):
return (obj,)
try:
return iter(obj)
except TypeError:
return (obj,)
def iterate(*args):
return chain.from_iterable(map(to_iterable, args))
def flatten(*args):
for arg in args:
if is_iterable(arg):
for sub in arg:
yield from flatten(sub)
else:
yield arg
def riffle(iterable, separator):
iterable = iter(iterable)
try:
yield next(iterable)
for el in iterable:
yield separator
yield el
except StopIteration:
pass
def partition(iterable, n):
"""Yield successive n-sized chunks from l."""
iterable = iter(iterable)
res = tuple(islice(iterable, n))
while len(res) != 0:
yield res
res = tuple(islice(iterable, n))