1 #!/usr/bin/env python 2 3 """ 4 Functional operations for iterators. 5 6 Copyright (C) 2015, 2016, 2017 Paul Boddie <paul@boddie.org.uk> 7 8 This program is free software; you can redistribute it and/or modify it under 9 the terms of the GNU General Public License as published by the Free Software 10 Foundation; either version 3 of the License, or (at your option) any later 11 version. 12 13 This program is distributed in the hope that it will be useful, but WITHOUT 14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 15 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 16 details. 17 18 You should have received a copy of the GNU General Public License along with 19 this program. If not, see <http://www.gnu.org/licenses/>. 20 """ 21 22 def filter(function, sequence): 23 24 """ 25 Apply 'function' to each element in 'sequence', returning a sequence of all 26 elements for which the result of the function evaluated to a true value. 27 """ 28 29 l = [] 30 for i in sequence: 31 if function(i): 32 l.append(i) 33 return l 34 35 def map(function, sequence): 36 37 """ 38 Apply 'function' to each element of 'sequence' in turn, appending the result 39 to a new sequence containing all results. 40 """ 41 42 l = [] 43 for i in sequence: 44 l.append(function(i)) 45 return l 46 47 _reduce_default = object() 48 49 def reduce(function, sequence, initial=_reduce_default): 50 51 """ 52 Using 'function', reduce the given 'sequence' to a single result. 53 54 With no 'initial' value specified, the first two elements in the 'sequence' 55 are used with the function to produce an initial result. With an initial 56 result available, a subsequent result is computed by using the initial 57 result and the next element in the sequence with the function. 58 59 All subsequent results are computed using the current result and the next 60 available element with the function. This continues for all remaining 61 elements until the end of the sequence is reached. 62 """ 63 64 result = initial 65 66 for i in sequence: 67 if result is _reduce_default: 68 result = i 69 else: 70 result = function(result, i) 71 72 return result 73 74 def zip(args): 75 76 """ 77 Zip the given 'args' together, producing for each index position tuples 78 containing the values for that position from each of the 'args'. 79 """ 80 81 result = [] 82 pos = 0 83 84 # Repeat until one of the arguments runs out of elements. 85 86 while True: 87 l = [] 88 89 # Visit each argument in turn, collecting elements in the given 90 # position. 91 92 for arg in args: 93 try: 94 l.append(arg[pos]) 95 except IndexError: 96 return result 97 98 result.append(tuple(l)) 99 pos += 1 100 101 # vim: tabstop=4 expandtab shiftwidth=4