• Itertools. Part2

I’m glad you like the previous article where I showed you some CheckiO solutions using combinatoric generators from itertools.

I have decided not to wait for too long and show you some other functions and solutions from CheckiO. I choose most popular based on statistic I have showed before.

chain - iterates from all all passed iterables

In: list(itertools.chain('ABC', 'DEF'))
Out: ['A', 'B', 'C', 'D', 'E', 'F']

In: list(itertools.chain('ABC', 'DEF', [1,2,3]))
Out: ['A', 'B', 'C', 'D', 'E', 'F', 1, 2, 3]

Solutions: gyahun_dash's solution for How to find friends, And again, gyahun_dash's and his solution for Cipher Crossword

cycle - iterate through iterator over and over again

cycle('ABCD') --> A B C D A B C D A B C D …

Solutions: DiZ’s solution for Vigenere Cipher is also using accumulate function with cycle.

accumulate - accomulates iterate values while iterate. (starting with Python3)

In: list(itertools.accumulate([1,2,3,4,5]))
Out: [1, 3, 6, 10, 15]

In: list(itertools.accumulate('ABC'))
Out: ['A', 'AB', 'ABC']

By default - summing, but it can be changed

In: list(itertools.accumulate([1,2,3,4,5], lambda a, b: a*b))
Out: [1, 2, 6, 24, 120]

Solutions: I can’t avoid veky’s creative solutions for Vigenere Cipher

repeat - works the same way as cycle, but this time it repeats the same element endlessly. Repeat has an additional arguments (times), with this argument it will be repeated limited amount of times

repeat(8) --> 8 8 8 8 8 ...

repeat(10, 3) --> 10 10 10

Solutions: eiichi solution of Speech Module might be an example of using repeat.

Now let’s check some really interesting function, such as groupby that makes an iterator that returns consecutive keys and groups from the iterable.

In: [[a, list(b)] for a,b in itertools.groupby('AAAABBBBCCCSSS')]
[['A', ['A', 'A', 'A', 'A']],
 ['B', ['B', 'B', 'B', 'B']],
 ['C', ['C', 'C', 'C']],
 ['S', ['S', 'S', 'S']]]

In: [[a, list(b)] for a,b in itertools.groupby('AAAABBBBAAAA')]
[['A', ['A', 'A', 'A', 'A']],
 ['B', ['B', 'B', 'B', 'B']],
 ['A', ['A', 'A', 'A', 'A']]]

groupby has an additional parameter key, that allows you to define grouping rules

In [9]: [[a, list(b)] for a,b in itertools.groupby('AAAABBBaaabbBCaCCSSssSss', key=lambda a: a.isupper())]
[[True, ['A', 'A', 'A', 'A', 'B', 'B', 'B']],
 [False, ['a', 'a', 'a', 'b', 'b']],
 [True, ['B', 'C']],
 [False, ['a']],
 [True, ['C', 'C', 'S', 'S']],
 [False, ['s', 's']],
 [True, ['S']],
 [False, ['s', 's']]]

Solutions: nickie's solution for Find Sequence, almoust oneliner from Adam.Michalak’s solution of Verify anagrams, makoto_yamagata solution of Spaceship landing strip

zip_longest makes an iterator that aggregates elements from each of the iterables. If the iterables are of uneven length, missing values are filled-in with fillvalue.

In: list(itertools.zip_longest([1,2,3,5], [4,5,6]))
Out: [(1, 4), (2, 5), (3, 6), (5, None)]

In: list(itertools.zip_longest([1,2,3,5], [4,5,6], fillvalue=0))
Out: [(1, 4), (2, 5), (3, 6), (5, 0)]

Solutions: Absolute champion that use this function is PositronicLlama’s solution of Funny addition, bryukh’s very well commented solution for The Hidden Word

starmap is basically map version2. Roughly equivalent to:

def starmap(function, iterable):
    for args in iterable:
        yield function(*args)

In: list(itertools.starmap(pow, [(2,5), (3,2), (10,3)]))
Out: [32, 9, 1000]

Solutions: Creative solution of Roman Numerals from gyahun_dash

takewhile makes an iterator that returns elements from the iterable as long as the predicate is true.

In: list(itertools.takewhile(lambda x: x<5, [1,4,6,4,1]))
Out: [1, 4]

Solutions: bryukh’s solution for Spaceship landing strip, Feed Pigeons by ale1ster, gyahun_dash’s solution for IP Network: Route Summarization

Even though on CheckiO you can find a lot of creative solutions - Python documentation has some interesting recipes as well.

PS: Special request from veky :)

compress (New in version 3.1) makes an iterator that filters elements from data returning only those that have a corresponding element in selectors that evaluates to True and roughly equivalent to:

def compress(data, selectors):
    # compress('ABCDEF', [1,0,1,0,1,1]) --> A C E F
    return (d for d, s in zip(data, selectors) if s)

In: list(itertools.compress('ABC', [1,0,1]))
Out: ['A', 'C']

Solutions: Pohmelie’s solution for Loading Cargo, veghadam1991’s solution for Stair steps, And.. suddenly solutions for Fizz Buzz by nilp0inter

Welcome to CheckiO - games for coders where you can improve your codings skills.

The main idea behind these games is to give you the opportunity to learn by exchanging experience with the rest of the community. Every day we are trying to find interesting solutions for you to help you become a better coder.

Join the Game