Skip to content

Commit

Permalink
Merge pull request #192 from erikrose/il-rr-notes
Browse files Browse the repository at this point in the history
Additional tests and notes on performance for interleave_longest and roundrobin
  • Loading branch information
bbayles committed Jan 11, 2018
2 parents c9f53f4 + 821450b commit f450ab4
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 25 deletions.
1 change: 1 addition & 0 deletions .gitignore
Expand Up @@ -2,6 +2,7 @@

# Packages
*.egg
*.eggs
*.egg-info
dist
build
Expand Down
6 changes: 5 additions & 1 deletion more_itertools/more.py
Expand Up @@ -801,9 +801,13 @@ def interleave_longest(*iterables):
>>> list(interleave_longest([1, 2, 3], [4, 5], [6, 7, 8]))
[1, 4, 6, 2, 5, 7, 3, 8]
This function produces the same output as :func:`roundrobin`, but may
perform better for some inputs (in particular when the number of iterables
is large).
"""
i = chain.from_iterable(zip_longest(*iterables, fillvalue=_marker))
return filter(lambda x: x is not _marker, i)
return (x for x in i if x is not _marker)


def collapse(iterable, base_type=None, levels=None):
Expand Down
4 changes: 3 additions & 1 deletion more_itertools/recipes.py
Expand Up @@ -300,7 +300,9 @@ def roundrobin(*iterables):
>>> list(roundrobin('ABC', 'D', 'EF'))
['A', 'D', 'E', 'B', 'F', 'C']
See :func:`interleave_longest` for a slightly faster implementation.
This function produces the same output as :func:`interleave_longest`, but
may perform better for some inputs (in particular when the number of
iterables is small).
"""
# Recipe credited to George Sakkis
Expand Down
54 changes: 32 additions & 22 deletions more_itertools/tests/test_more.py
Expand Up @@ -650,34 +650,44 @@ def test_zero(self):
self.assertEqual(list(new_iterable), ['a', 'b', 'c'])


class TestInterleave(TestCase):
"""Tests for ``interleave()`` and ``interleave_longest()``"""
class InterleaveTests(TestCase):
def test_even(self):
actual = list(mi.interleave([1, 4, 7], [2, 5, 8], [3, 6, 9]))
expected = [1, 2, 3, 4, 5, 6, 7, 8, 9]
self.assertEqual(actual, expected)

def test_interleave(self):
l = [[1, 2, 3], [4, 5], [6, 7, 8]]
self.assertEqual(list(mi.interleave(*l)), [1, 4, 6, 2, 5, 7])
def test_short(self):
actual = list(mi.interleave([1, 4], [2, 5, 7], [3, 6, 8]))
expected = [1, 2, 3, 4, 5, 6]
self.assertEqual(actual, expected)

l = [[1, 2], [3, 4, 5], [6, 7, 8]]
self.assertEqual(list(mi.interleave(*l)), [1, 3, 6, 2, 4, 7])
def test_mixed_types(self):
it_list = ['a', 'b', 'c', 'd']
it_str = '12345'
it_inf = count()
actual = list(mi.interleave(it_list, it_str, it_inf))
expected = ['a', '1', 0, 'b', '2', 1, 'c', '3', 2, 'd', '4', 3]
self.assertEqual(actual, expected)

l = [[1, 2, 3], [4, 5, 6], [7, 8]]
self.assertEqual(list(mi.interleave(*l)), [1, 4, 7, 2, 5, 8])

def test_interleave_longest(self):
l = [[1, 2, 3], [4, 5], [6, 7, 8]]
self.assertEqual(
list(mi.interleave_longest(*l)), [1, 4, 6, 2, 5, 7, 3, 8]
)
class InterleaveLongestTests(TestCase):
def test_even(self):
actual = list(mi.interleave_longest([1, 4, 7], [2, 5, 8], [3, 6, 9]))
expected = [1, 2, 3, 4, 5, 6, 7, 8, 9]
self.assertEqual(actual, expected)

l = [[1, 2], [3, 4, 5], [6, 7, 8]]
self.assertEqual(
list(mi.interleave_longest(*l)), [1, 3, 6, 2, 4, 7, 5, 8]
)
def test_short(self):
actual = list(mi.interleave_longest([1, 4], [2, 5, 7], [3, 6, 8]))
expected = [1, 2, 3, 4, 5, 6, 7, 8]
self.assertEqual(actual, expected)

l = [[1, 2, 3], [4, 5, 6], [7, 8]]
self.assertEqual(
list(mi.interleave_longest(*l)), [1, 4, 7, 2, 5, 8, 3, 6]
)
def test_mixed_types(self):
it_list = ['a', 'b', 'c', 'd']
it_str = '12345'
it_gen = (x for x in range(3))
actual = list(mi.interleave_longest(it_list, it_str, it_gen))
expected = ['a', '1', 0, 'b', '2', 1, 'c', '3', 2, 'd', '4', '5']
self.assertEqual(actual, expected)


class TestCollapse(TestCase):
Expand Down
2 changes: 1 addition & 1 deletion setup.cfg
@@ -1,3 +1,3 @@
[flake8]
exclude = ./docs/conf.py
exclude = ./docs/conf.py, .eggs/
ignore = E731, E741, F999

0 comments on commit f450ab4

Please sign in to comment.