Skip to content

Commit 3ed417c

Browse files
committed
added SequenceZip as an alternative to builtin zip
1 parent 40b467a commit 3ed417c

File tree

1 file changed

+55
-0
lines changed

1 file changed

+55
-0
lines changed

larray/util/misc.py

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -778,3 +778,58 @@ def __enter__(self):
778778
def __exit__(self, type_, value, traceback):
779779
if self.close_store:
780780
self.store.close()
781+
782+
783+
class SequenceZip(object):
784+
"""
785+
Represents the "combination" of several sequences.
786+
787+
This is very similar to python's builtin zip but only accepts sequences and acts as a Sequence (it can be
788+
indexed and has a len).
789+
790+
Parameters
791+
----------
792+
sequences : Iterable of Sequence
793+
Sequences to combine.
794+
795+
Examples
796+
--------
797+
>>> z = SequenceZip([['a', 'b', 'c'], [1, 2, 3]])
798+
>>> for i in range(len(z)):
799+
... print(z[i])
800+
('a', 1)
801+
('b', 2)
802+
('c', 3)
803+
>>> for v in z:
804+
... print(v)
805+
('a', 1)
806+
('b', 2)
807+
('c', 3)
808+
>>> list(z[1:4])
809+
[('b', 2), ('c', 3)]
810+
"""
811+
def __init__(self, sequences):
812+
self.sequences = sequences
813+
length = len(sequences[0])
814+
bad_length_seqs = [i for i, s in enumerate(sequences[1:], start=1) if len(s) != length]
815+
if bad_length_seqs:
816+
first_bad = bad_length_seqs[0]
817+
raise ValueError("sequence {} has a length of {} which is different from the length of the "
818+
"first sequence ({})".format(first_bad, len(sequences[first_bad]), length))
819+
self._length = length
820+
821+
def __len__(self):
822+
return self._length
823+
824+
def __getitem__(self, key):
825+
if isinstance(key, (int, np.integer)):
826+
return tuple(seq[key] for seq in self.sequences)
827+
else:
828+
assert isinstance(key, slice), "key (%s) has invalid type (%s)" % (key, type(key))
829+
return SequenceZip([seq[key] for seq in self.sequences])
830+
831+
def __iter__(self):
832+
return iter(zip(*self.sequences)) if PY2 else zip(*self.sequences)
833+
834+
def __repr__(self):
835+
return 'SequenceZip({})'.format(self.sequences)

0 commit comments

Comments
 (0)