2018-03-30 18:19:23 -07:00
|
|
|
import itertools as it
|
2018-03-31 15:11:35 -07:00
|
|
|
import numpy as np
|
2018-03-30 18:19:23 -07:00
|
|
|
|
2018-04-06 13:58:59 -07:00
|
|
|
|
2018-03-30 18:19:23 -07:00
|
|
|
def remove_list_redundancies(l):
|
|
|
|
"""
|
|
|
|
Used instead of list(set(l)) to maintain order
|
|
|
|
Keeps the last occurance of each element
|
|
|
|
"""
|
|
|
|
reversed_result = []
|
|
|
|
used = set()
|
|
|
|
for x in reversed(l):
|
2018-04-06 13:58:59 -07:00
|
|
|
if x not in used:
|
2018-03-30 18:19:23 -07:00
|
|
|
reversed_result.append(x)
|
|
|
|
used.add(x)
|
|
|
|
reversed_result.reverse()
|
|
|
|
return reversed_result
|
|
|
|
|
2018-04-06 13:58:59 -07:00
|
|
|
|
2018-03-30 18:19:23 -07:00
|
|
|
def list_update(l1, l2):
|
|
|
|
"""
|
|
|
|
Used instead of list(set(l1).update(l2)) to maintain order,
|
|
|
|
making sure duplicates are removed from l1, not l2.
|
|
|
|
"""
|
2018-08-09 17:56:05 -07:00
|
|
|
return [e for e in l1 if e not in l2] + list(l2)
|
2018-04-06 13:58:59 -07:00
|
|
|
|
2018-03-30 18:19:23 -07:00
|
|
|
|
|
|
|
def list_difference_update(l1, l2):
|
2018-08-09 17:56:05 -07:00
|
|
|
return [e for e in l1 if e not in l2]
|
2018-04-06 13:58:59 -07:00
|
|
|
|
2018-03-30 18:19:23 -07:00
|
|
|
|
|
|
|
def all_elements_are_instances(iterable, Class):
|
2018-08-09 17:56:05 -07:00
|
|
|
return all([isinstance(e, Class) for e in iterable])
|
2018-04-06 13:58:59 -07:00
|
|
|
|
2018-03-30 18:19:23 -07:00
|
|
|
|
|
|
|
def adjacent_pairs(objects):
|
2018-08-09 17:56:05 -07:00
|
|
|
return list(zip(objects, list(objects[1:]) + [objects[0]]))
|
2018-04-06 13:58:59 -07:00
|
|
|
|
2018-03-30 18:19:23 -07:00
|
|
|
|
|
|
|
def batch_by_property(items, property_func):
|
|
|
|
"""
|
|
|
|
Takes in a list, and returns a list of tuples, (batch, prop)
|
|
|
|
such that all items in a batch have the same output when
|
|
|
|
put into property_func, and such that chaining all these
|
2018-06-11 10:40:17 -07:00
|
|
|
batches together would give the original list (i.e. order is
|
|
|
|
preserved)
|
2018-03-30 18:19:23 -07:00
|
|
|
"""
|
|
|
|
batch_prop_pairs = []
|
2018-04-06 13:58:59 -07:00
|
|
|
|
2018-03-30 18:19:23 -07:00
|
|
|
def add_batch_prop_pair(batch):
|
|
|
|
if len(batch) > 0:
|
|
|
|
batch_prop_pairs.append(
|
|
|
|
(batch, property_func(batch[0]))
|
|
|
|
)
|
|
|
|
curr_batch = []
|
|
|
|
curr_prop = None
|
|
|
|
for item in items:
|
|
|
|
prop = property_func(item)
|
|
|
|
if prop != curr_prop:
|
|
|
|
add_batch_prop_pair(curr_batch)
|
|
|
|
curr_prop = prop
|
|
|
|
curr_batch = [item]
|
|
|
|
else:
|
|
|
|
curr_batch.append(item)
|
|
|
|
add_batch_prop_pair(curr_batch)
|
|
|
|
return batch_prop_pairs
|
|
|
|
|
2018-04-06 13:58:59 -07:00
|
|
|
|
2018-03-30 18:19:23 -07:00
|
|
|
def tuplify(obj):
|
|
|
|
if isinstance(obj, str):
|
|
|
|
return (obj,)
|
|
|
|
try:
|
|
|
|
return tuple(obj)
|
2018-08-10 15:12:49 -07:00
|
|
|
except TypeError:
|
2018-03-30 18:19:23 -07:00
|
|
|
return (obj,)
|
|
|
|
|
2018-04-06 13:58:59 -07:00
|
|
|
|
2018-03-30 18:19:23 -07:00
|
|
|
def stretch_array_to_length(nparray, length):
|
|
|
|
curr_len = len(nparray)
|
|
|
|
if curr_len > length:
|
2018-04-06 13:58:59 -07:00
|
|
|
raise Warning(
|
|
|
|
"Trying to stretch array to a length shorter than its own")
|
|
|
|
indices = np.arange(length) / float(length)
|
2018-03-30 18:19:23 -07:00
|
|
|
indices *= curr_len
|
|
|
|
return nparray[indices.astype('int')]
|
|
|
|
|
2018-04-06 13:58:59 -07:00
|
|
|
|
2018-03-30 18:19:23 -07:00
|
|
|
def make_even(iterable_1, iterable_2):
|
|
|
|
list_1, list_2 = list(iterable_1), list(iterable_2)
|
|
|
|
length = max(len(list_1), len(list_2))
|
|
|
|
return (
|
2018-08-10 15:12:49 -07:00
|
|
|
[list_1[(n * len(list_1)) // length] for n in range(length)],
|
|
|
|
[list_2[(n * len(list_2)) // length] for n in range(length)]
|
2018-03-30 18:19:23 -07:00
|
|
|
)
|
|
|
|
|
2018-04-06 13:58:59 -07:00
|
|
|
|
2018-03-30 18:19:23 -07:00
|
|
|
def make_even_by_cycling(iterable_1, iterable_2):
|
|
|
|
length = max(len(iterable_1), len(iterable_2))
|
|
|
|
cycle1 = it.cycle(iterable_1)
|
|
|
|
cycle2 = it.cycle(iterable_2)
|
|
|
|
return (
|
2018-07-11 11:38:59 -07:00
|
|
|
[next(cycle1) for x in range(length)],
|
|
|
|
[next(cycle2) for x in range(length)]
|
2018-03-30 18:19:23 -07:00
|
|
|
)
|
|
|
|
|
2018-04-06 13:58:59 -07:00
|
|
|
|
|
|
|
def remove_nones(sequence):
|
2018-08-09 17:56:05 -07:00
|
|
|
return [x for x in sequence if x]
|
2018-03-30 18:19:23 -07:00
|
|
|
|
2018-08-20 15:50:52 -07:00
|
|
|
|
2018-04-06 13:58:59 -07:00
|
|
|
# Note this is redundant with it.chain
|
2018-03-30 18:19:23 -07:00
|
|
|
|
|
|
|
|
2018-04-06 13:58:59 -07:00
|
|
|
def concatenate_lists(*list_of_lists):
|
|
|
|
return [item for l in list_of_lists for item in l]
|