@@ -21,13 +21,16 @@ def accumulate(iterable, func=lambda x, y: x + y, initial=None):
21
21
total = func (total , element )
22
22
yield total
23
23
24
+
24
25
# chain('abcd',[],range(5))) --> 'a' 'b' 'c' 'd' 0 1 2 3 4
25
26
class chain :
26
27
def __init__ (self , * iterables ):
27
28
self .iterables = list (iterables )
28
29
self .it = iter ([])
30
+
29
31
def __iter__ (self ):
30
32
return self
33
+
31
34
def __next__ (self ):
32
35
while True :
33
36
try :
@@ -38,12 +41,14 @@ def __next__(self):
38
41
continue
39
42
except IndexError :
40
43
raise StopIteration
44
+
41
45
# chain.from_iterable(['ABC', 'DEF']) --> 'A' 'B' 'C' 'D' 'E' 'F'
42
46
@staticmethod
43
- def from_iterable (iterables ):
47
+ def from_iterable (iterables ):
44
48
for it in iterables :
45
49
yield from it
46
50
51
+
47
52
# combinations('ABCD', 2) --> ('A','B') ('A','C') ('A','D') ('B','C') ('B','D') ('C','D')
48
53
def combinations (iterable , r ):
49
54
pool = tuple (iterable )
@@ -65,6 +70,7 @@ def combinations(iterable, r):
65
70
indices [j ] = indices [j - 1 ] + 1
66
71
yield tuple (pool [i ] for i in indices )
67
72
73
+
68
74
# combinations_with_replacement('ABC', 2) --> ('A','A') ('A','B') ('A','C') ('B','B') ('B','C') ('C','C')
69
75
def combinations_with_replacement (iterable , r ):
70
76
pool = tuple (iterable )
@@ -84,21 +90,24 @@ def combinations_with_replacement(iterable, r):
84
90
indices [index :] = [indices [index ] + 1 ] * (r - index )
85
91
yield tuple (pool [i ] for i in indices )
86
92
93
+
87
94
# compress('ABCDEF', [1,0,1,0,1,1]) --> A C E F
88
95
def compress (data , selectors ):
89
96
return (d for d , s in zip (data , selectors ) if s )
90
97
98
+
91
99
# count(4, 3) --> 4 7 10 13 16 19 ....
92
100
def count (start = 0 , step = 1 ):
93
101
while True :
94
102
yield start
95
103
start += step
96
104
105
+
97
106
# cycle('abc') --> a b c a b c a b c a ....
98
107
def cycle (iterable ):
99
108
try :
100
109
len (iterable )
101
- except TypeError : # len() not defined: Assume p is a finite iterable: We cache the elements.
110
+ except TypeError : # len() not defined: Assume p is a finite iterable: We cache the elements.
102
111
cache = []
103
112
for i in iterable :
104
113
yield i
@@ -107,6 +116,7 @@ def cycle(iterable):
107
116
while iterable :
108
117
yield from iterable
109
118
119
+
110
120
# # dropwhile(lambda x: x<5, [1,4,6,4,1]) --> 6 4 1
111
121
def dropwhile (predicate , iterable ):
112
122
it = iter (iterable )
@@ -117,6 +127,7 @@ def dropwhile(predicate, iterable):
117
127
for x in it :
118
128
yield x
119
129
130
+
120
131
# filterfalse(lambda x: x%2, range(10)) --> 0 2 4 6 8
121
132
def filterfalse (predicate , iterable ):
122
133
if predicate is None :
@@ -125,38 +136,48 @@ def filterfalse(predicate, iterable):
125
136
if not predicate (x ):
126
137
yield x
127
138
139
+
128
140
# groupby('aaaabbbccdaa'))) --> ('a', gen1) ('b', gen2) ('c', gen3) ('d', gen4) ('a', gen5)
129
141
# where gen1 --> a a a a, gen2 --> b b b, gen3 --> c c, gen4 --> d, gen5 --> a a
130
142
def groupby (iterable , key = None ):
131
143
it = iter (iterable )
132
144
keyf = key if key is not None else lambda x : x
145
+
133
146
def ggen (ktgt ):
134
147
nonlocal cur , kcur
135
148
while kcur == ktgt :
136
149
yield cur
137
150
try :
138
- cur = next (it ); kcur = keyf (cur )
151
+ cur = next (it )
152
+ kcur = keyf (cur )
139
153
except StopIteration :
140
- break
141
- kcur = kold = object () # need an object that never can be a returned from key function
154
+ break
155
+
156
+ kcur = kold = object () # need an object that never can be a returned from key function
142
157
while True :
143
- while kcur == kold : # not all iterables with the same (old) key were used up by ggen, so use them up here
158
+ while (
159
+ kcur == kold
160
+ ): # not all iterables with the same (old) key were used up by ggen, so use them up here
144
161
try :
145
- cur = next (it ); kcur = keyf (cur )
162
+ cur = next (it )
163
+ kcur = keyf (cur )
146
164
except StopIteration :
147
165
return
148
166
kold = kcur
149
167
yield (kcur , ggen (kcur ))
150
168
169
+
151
170
# islice('abcdefghij', 2, None, 3)) --> c f i
152
171
# islice(range(10), 2, 6, 2)) --> 2 4
153
172
def islice (iterable , * sargs ):
154
173
if len (sargs ) < 1 or len (sargs ) > 3 :
155
- raise TypeError ('islice expected at least 2, at most 4 arguments, got {:d}' .format (len (sargs )+ 1 ))
174
+ raise TypeError (
175
+ "islice expected at least 2, at most 4 arguments, got {:d}" .format (len (sargs ) + 1 )
176
+ )
156
177
step = 1 if len (sargs ) < 3 else sargs [2 ]
157
178
step = 1 if step is None else step
158
179
if step <= 0 :
159
- raise ValueError (' step for islice() must be a positive integer or None' )
180
+ raise ValueError (" step for islice() must be a positive integer or None" )
160
181
start = 0 if len (sargs ) < 2 else sargs [0 ]
161
182
stop = sargs [0 ] if len (sargs ) == 1 else sargs [1 ]
162
183
it = iter (iterable )
@@ -173,18 +194,20 @@ def islice(iterable, *sargs):
173
194
except StopIteration :
174
195
return
175
196
197
+
176
198
# pairwise(range(5)) --> (0,1) (1,2) (2,3) (3,4)
177
199
# pairwise('abcdefg') --> ('a','b') ('b','c') ('c','d') ('d','e') ('e','f') ('f','g')
178
200
def pairwise (iterable ):
179
- it = iter (iterable )
201
+ it = iter (iterable )
180
202
try :
181
203
l = next (it )
182
204
while True :
183
205
c = next (it )
184
206
yield l , c
185
207
l = c
186
208
except StopIteration :
187
- return
209
+ return
210
+
188
211
189
212
# permutations('ABCD', 2) --> AB AC AD BA BC BD CA CB CD DA DB DC
190
213
# permutations(range(3)) --> 012 021 102 120 201 210
@@ -211,6 +234,7 @@ def permutations(iterable, r=None):
211
234
else :
212
235
return
213
236
237
+
214
238
# product('ABCD', 'xy') --> ('A','x') ('A','y') ('B','x') ('B','y') ('C','x') ('C','y') ('D','x') ('D','y')
215
239
# product(range(2), repeat=3) --> 000 001 010 011 100 101 110 111 # but in tuples, of course
216
240
def product (* args , repeat = 1 ):
@@ -221,6 +245,7 @@ def product(*args, repeat=1):
221
245
for prod in result :
222
246
yield tuple (prod )
223
247
248
+
224
249
# repeat(10, 3) --> 10 10 10
225
250
def repeat (obj , times = None ):
226
251
if times is None :
@@ -230,11 +255,13 @@ def repeat(obj, times=None):
230
255
for _ in range (times ):
231
256
yield obj
232
257
258
+
233
259
# starmap(pow, [(2,5), (3,2), (10,3)]) --> 32 9 1000
234
260
def starmap (function , iterable ):
235
261
for args in iterable :
236
262
yield function (* args )
237
263
264
+
238
265
# takewhile(lambda x: x<5, [1,4,6,4,1]) --> 1 4
239
266
def takewhile (predicate , iterable ):
240
267
for x in iterable :
@@ -243,27 +270,33 @@ def takewhile(predicate, iterable):
243
270
else :
244
271
break
245
272
273
+
246
274
# tee(range(2,10), 3) --> (it1, it2, it3) all parallel generators, but dependent on original generator (e.g. range(2,10))
247
275
# --> (min(it1), max(it2), sum(it3)) --> (2, 9, 44)
248
276
def tee (iterable , n = 2 ):
249
- if iter (iterable ) is not iter (iterable ): # save buffer for special cases that iterable is range, tuple, list ...
277
+ if iter (iterable ) is not iter (
278
+ iterable
279
+ ): # save buffer for special cases that iterable is range, tuple, list ...
250
280
return [iter (iterable ) for _ in range (n )] # that have independent iterators
251
281
it = iter (iterable )
252
282
if n < 1 :
253
283
return ()
254
284
elif n == 1 :
255
285
return (it ,)
256
- buf = [] # Buffer, contains stored values from itr
257
- ibuf = [0 ]* n # Indices of the individual generators, could be array('H', [0]*n)
258
- def gen (k ): # but we have no 0 in ibuf in MP
259
- nonlocal buf , ibuf # These are bound to the generators as closures
286
+ buf = [] # Buffer, contains stored values from itr
287
+ ibuf = [0 ] * n # Indices of the individual generators, could be array('H', [0]*n)
288
+
289
+ def gen (k ): # but we have no 0 in ibuf in MP
290
+ nonlocal buf , ibuf # These are bound to the generators as closures
260
291
while True :
261
- if ibuf [k ] < len (buf ): # We get an object stored in the buffer.
292
+ if ibuf [k ] < len (buf ): # We get an object stored in the buffer.
262
293
r = buf [ibuf [k ]]
263
294
ibuf [k ] += 1
264
- if ibuf [k ] == 1 : # If we got the first object in the buffer,
265
- if 0 not in ibuf : # then check if other generators do not wait anymore on it
266
- buf .pop (0 ) # so it may be popped left. Afterwards decrease all indices by 1.
295
+ if ibuf [k ] == 1 : # If we got the first object in the buffer,
296
+ if 0 not in ibuf : # then check if other generators do not wait anymore on it
297
+ buf .pop (
298
+ 0
299
+ ) # so it may be popped left. Afterwards decrease all indices by 1.
267
300
for i in range (n ):
268
301
ibuf [i ] -= 1
269
302
elif ibuf [k ] == len (buf ):
@@ -273,8 +306,10 @@ def gen(k): # but we have no 0 in ibuf in MP
273
306
ibuf [k ] += 1
274
307
except StopIteration :
275
308
return
276
- yield r # The returned generators are not thread-safe. For that the access to the
277
- return tuple (gen (i ) for i in range (n )) # shared buf and ibuf should be protected by locks.
309
+ yield r # The returned generators are not thread-safe. For that the access to the
310
+
311
+ return tuple (gen (i ) for i in range (n )) # shared buf and ibuf should be protected by locks.
312
+
278
313
279
314
# zip_longest('ABCD', 'xy', fillvalue='-') --> ('A','x') ('B','y') ('C','-') ('D','-')
280
315
def zip_longest (* args , fillvalue = None ):
@@ -299,19 +334,18 @@ def zip_longest(*args, fillvalue=None):
299
334
300
335
# # Full analog of CPython builtin iter with 2 arguments
301
336
# def iter(*args):
302
- #
337
+ #
303
338
# if len(args) == 1:
304
339
# return builtins.iter(args[0])
305
- #
340
+ #
306
341
# class _iter:
307
- #
342
+ #
308
343
# def __init__(self, args):
309
344
# self.f, self.sentinel = args
310
345
# def __next__(self):
311
346
# v = self.f()
312
347
# if v == self.sentinel:
313
348
# raise StopIteration
314
349
# return v
315
- #
350
+ #
316
351
# return _iter(args)
317
-
0 commit comments