-
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')] Out: [['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')] Out: [['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())] Out[9]: [[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