@@ -117,9 +117,9 @@ def __init__(self, items=None, *rest, use_list=False, match=None):
117117 def _xtra (self ): return None
118118 def _new (self , items , * args , ** kwargs ): return type (self )(items , * args , use_list = None , ** kwargs )
119119 def __getitem__ (self , idx ):
120+ "Retrieve `idx` (can be list of indices, or mask, or int) items"
120121 if isinstance (idx ,int ) and not hasattr (self .items ,'iloc' ): return self .items [idx ]
121122 return self ._get (idx ) if is_indexer (idx ) else L (self ._get (idx ), use_list = None )
122- def copy (self ): return self ._new (self .items .copy ())
123123
124124 def _get (self , i ):
125125 if is_indexer (i ) or isinstance (i ,slice ): return getattr (self .items ,'iloc' ,self .items )[i ]
@@ -143,7 +143,6 @@ def __eq__(self,b):
143143 if isinstance (b , (str ,dict )) or callable (b ): return False
144144 return all_equal (b ,self )
145145
146- def sorted (self , key = None , reverse = False , cmp = None , ** kwargs ): return self ._new (sorted_ex (self , key = key , reverse = reverse , cmp = cmp , ** kwargs ))
147146 def __iter__ (self ): return iter (self .items .itertuples () if hasattr (self .items ,'iloc' ) else self .items )
148147 def __contains__ (self ,b ): return b in self .items
149148 def __reversed__ (self ): return self ._new (reversed (self .items ))
@@ -158,88 +157,6 @@ def __addi__(a,b):
158157 a .items += list (b )
159158 return a
160159
161- @classmethod
162- def split (cls , s , sep = None , maxsplit = - 1 ): return cls (s .split (sep ,maxsplit ))
163- @classmethod
164- def splitlines (cls , s , keepends = False ): return cls (s .splitlines (keepends ))
165- @classmethod
166- def range (cls , a , b = None , step = None ): return cls (range_of (a , b = b , step = step ))
167-
168- def map (self , f , * args , ** kwargs ): return self ._new (map_ex (self , f , * args , gen = False , ** kwargs ))
169- def argwhere (self , f , negate = False , ** kwargs ): return self ._new (argwhere (self , f , negate , ** kwargs ))
170- def argfirst (self , f , negate = False ):
171- if negate : f = not_ (f )
172- return first (i for i ,o in self .enumerate () if f (o ))
173- def filter (self , f = noop , negate = False , ** kwargs ):
174- return self ._new (filter_ex (self , f = f , negate = negate , gen = False , ** kwargs ))
175-
176- def enumerate (self ): return L (enumerate (self ))
177- def renumerate (self ): return L (renumerate (self ))
178- def unique (self , sort = False , bidir = False , start = None ): return L (uniqueify (self , sort = sort , bidir = bidir , start = start ))
179- def val2idx (self ): return val2idx (self )
180- def cycle (self ): return cycle (self )
181- def groupby (self , key , val = noop ): return groupby (self , key , val = val )
182- def map_dict (self , f = noop , * args , ** kwargs ): return {k :f (k , * args ,** kwargs ) for k in self }
183- def map_first (self , f = noop , g = noop , * args , ** kwargs ):
184- return first (self .map (f , * args , ** kwargs ), g )
185-
186- def itemgot (self , * idxs ):
187- x = self
188- for idx in idxs : x = x .map (itemgetter (idx ))
189- return x
190- def attrgot (self , k , default = None ):
191- return self .map (lambda o : o .get (k ,default ) if isinstance (o , dict ) else nested_attr (o ,k ,default ))
192-
193- def starmap (self , f , * args , ** kwargs ): return self ._new (itertools .starmap (partial (f ,* args ,** kwargs ), self ))
194- def zip (self , cycled = False ): return self ._new ((zip_cycle if cycled else zip )(* self ))
195- def zipwith (self , * rest , cycled = False ): return self ._new ([self , * rest ]).zip (cycled = cycled )
196- def map_zip (self , f , * args , cycled = False , ** kwargs ): return self .zip (cycled = cycled ).starmap (f , * args , ** kwargs )
197- def map_zipwith (self , f , * rest , cycled = False , ** kwargs ): return self .zipwith (* rest , cycled = cycled ).starmap (f , ** kwargs )
198- def shuffle (self ):
199- it = copy (self .items )
200- random .shuffle (it )
201- return self ._new (it )
202-
203- def concat (self ): return self ._new (itertools .chain .from_iterable (self .map (L )))
204- def reduce (self , f , initial = None ): return reduce (f , self ) if initial is None else reduce (f , self , initial )
205- def sum (self ): return self .reduce (operator .add , 0 )
206- def product (self ): return self .reduce (operator .mul , 1 )
207- def setattrs (self , attr , val ): [setattr (o ,attr ,val ) for o in self ]
208-
209- # %% ../nbs/02_foundation.ipynb
210- add_docs (L ,
211- __getitem__ = "Retrieve `idx` (can be list of indices, or mask, or int) items" ,
212- range = "Class Method: Same as `range`, but returns `L`. Can pass collection for `a`, to use `len(a)`" ,
213- split = "Class Method: Same as `str.split`, but returns an `L`" ,
214- splitlines = "Class Method: Same as `str.splitlines`, but returns an `L`" ,
215- copy = "Same as `list.copy`, but returns an `L`" ,
216- sorted = "New `L` sorted by `key`, using `sort_ex`. If key is str use `attrgetter`; if int use `itemgetter`" ,
217- unique = "Unique items, in stable order" ,
218- val2idx = "Dict from value to index" ,
219- filter = "Create new `L` filtered by predicate `f`, passing `args` and `kwargs` to `f`" ,
220- argwhere = "Like `filter`, but return indices for matching items" ,
221- argfirst = "Return index of first matching item" ,
222- map = "Create new `L` with `f` applied to all `items`, passing `args` and `kwargs` to `f`" ,
223- map_first = "First element of `map_filter`" ,
224- map_dict = "Like `map`, but creates a dict from `items` to function results" ,
225- starmap = "Like `map`, but use `itertools.starmap`" ,
226- itemgot = "Create new `L` with item `idx` of all `items`" ,
227- attrgot = "Create new `L` with attr `k` (or value `k` for dicts) of all `items`." ,
228- cycle = "Same as `itertools.cycle`" ,
229- enumerate = "Same as `enumerate`" ,
230- renumerate = "Same as `renumerate`" ,
231- groupby = "Same as `fastcore.basics.groupby`" ,
232- zip = "Create new `L` with `zip(*items)`" ,
233- zipwith = "Create new `L` with `self` zip with each of `*rest`" ,
234- map_zip = "Combine `zip` and `starmap`" ,
235- map_zipwith = "Combine `zipwith` and `starmap`" ,
236- concat = "Concatenate all elements of list" ,
237- shuffle = "Same as `random.shuffle`, but not inplace" ,
238- reduce = "Wrapper for `functools.reduce`" ,
239- sum = "Sum of the items" ,
240- product = "Product of the items" ,
241- setattrs = "Call `setattr` on all items" )
242-
243160# %% ../nbs/02_foundation.ipynb
244161# Here we are fixing the signature of L. What happens is that the __call__ method on the MetaClass of L shadows the __init__
245162# giving the wrong signature (https://stackoverflow.com/questions/49740290/call-from-metaclass-shadows-signature-of-init).
@@ -249,6 +166,191 @@ def _f(items=None, *rest, use_list=False, match=None): ...
249166# %% ../nbs/02_foundation.ipynb
250167Sequence .register (L );
251168
169+ # %% ../nbs/02_foundation.ipynb
170+ @patch
171+ def unique (self :L , sort = False , bidir = False , start = None ):
172+ "Unique items, in stable order"
173+ return L (uniqueify (self , sort = sort , bidir = bidir , start = start ))
174+
175+ # %% ../nbs/02_foundation.ipynb
176+ @patch
177+ def val2idx (self :L ):
178+ "Dict from value to index"
179+ return val2idx (self )
180+
181+ # %% ../nbs/02_foundation.ipynb
182+ @patch (cls_method = True )
183+ def split (cls :L , s , sep = None , maxsplit = - 1 ):
184+ "Class Method: Same as `str.split`, but returns an `L`"
185+ return cls (s .split (sep ,maxsplit ))
186+
187+ # %% ../nbs/02_foundation.ipynb
188+ @patch (cls_method = True )
189+ def splitlines (cls :L , s , keepends = False ):
190+ "Class Method: Same as `str.splitlines`, but returns an `L`"
191+ return cls (s .splitlines (keepends ))
192+
193+ # %% ../nbs/02_foundation.ipynb
194+ @patch
195+ def groupby (self :L , key , val = noop ):
196+ "Same as `fastcore.basics.groupby`"
197+ return groupby (self , key , val = val )
198+
199+ # %% ../nbs/02_foundation.ipynb
200+ @patch
201+ def filter (self :L , f = noop , negate = False , ** kwargs ):
202+ "Create new `L` filtered by predicate `f`, passing `args` and `kwargs` to `f`"
203+ return self ._new (filter_ex (self , f = f , negate = negate , gen = False , ** kwargs ))
204+
205+ # %% ../nbs/02_foundation.ipynb
206+ @patch (cls_method = True )
207+ def range (cls :L , a , b = None , step = None ):
208+ "Class Method: Same as `range`, but returns `L`. Can pass collection for `a`, to use `len(a)`"
209+ return cls (range_of (a , b = b , step = step ))
210+
211+ # %% ../nbs/02_foundation.ipynb
212+ @patch
213+ def argwhere (self :L , f , negate = False , ** kwargs ):
214+ "Like `filter`, but return indices for matching items"
215+ return self ._new (argwhere (self , f , negate , ** kwargs ))
216+
217+ # %% ../nbs/02_foundation.ipynb
218+ @patch
219+ def enumerate (self :L ):
220+ "Same as `enumerate`"
221+ return L (enumerate (self ))
222+
223+ # %% ../nbs/02_foundation.ipynb
224+ @patch
225+ def renumerate (self :L ):
226+ "Same as `renumerate`"
227+ return L (renumerate (self ))
228+
229+ # %% ../nbs/02_foundation.ipynb
230+ @patch
231+ def argfirst (self :L , f , negate = False ):
232+ "Return index of first matching item"
233+ if negate : f = not_ (f )
234+ return first (i for i ,o in self .enumerate () if f (o ))
235+
236+ # %% ../nbs/02_foundation.ipynb
237+ @patch
238+ def map (self :L , f , * args , ** kwargs ):
239+ "Create new `L` with `f` applied to all `items`, passing `args` and `kwargs` to `f`"
240+ return self ._new (map_ex (self , f , * args , gen = False , ** kwargs ))
241+
242+ # %% ../nbs/02_foundation.ipynb
243+ @patch
244+ def starmap (self :L , f , * args , ** kwargs ):
245+ "Like `map`, but use `itertools.starmap`"
246+ return self ._new (itertools .starmap (partial (f ,* args ,** kwargs ), self ))
247+
248+ # %% ../nbs/02_foundation.ipynb
249+ @patch
250+ def map_dict (self :L , f = noop , * args , ** kwargs ):
251+ "Like `map`, but creates a dict from `items` to function results"
252+ return {k :f (k , * args ,** kwargs ) for k in self }
253+
254+ # %% ../nbs/02_foundation.ipynb
255+ @patch
256+ def zip (self :L , cycled = False ):
257+ "Create new `L` with `zip(*items)`"
258+ return self ._new ((zip_cycle if cycled else zip )(* self ))
259+
260+ # %% ../nbs/02_foundation.ipynb
261+ @patch
262+ def map_zip (self :L , f , * args , cycled = False , ** kwargs ):
263+ "Combine `zip` and `starmap`"
264+ return self .zip (cycled = cycled ).starmap (f , * args , ** kwargs )
265+
266+ # %% ../nbs/02_foundation.ipynb
267+ @patch
268+ def zipwith (self :L , * rest , cycled = False ):
269+ "Create new `L` with `self` zip with each of `*rest`"
270+ return self ._new ([self , * rest ]).zip (cycled = cycled )
271+
272+ # %% ../nbs/02_foundation.ipynb
273+ @patch
274+ def map_zipwith (self :L , f , * rest , cycled = False , ** kwargs ):
275+ "Combine `zipwith` and `starmap`"
276+ return self .zipwith (* rest , cycled = cycled ).starmap (f , ** kwargs )
277+
278+ # %% ../nbs/02_foundation.ipynb
279+ @patch
280+ def itemgot (self :L , * idxs ):
281+ "Create new `L` with item `idx` of all `items`"
282+ x = self
283+ for idx in idxs : x = x .map (itemgetter (idx ))
284+ return x
285+
286+ # %% ../nbs/02_foundation.ipynb
287+ @patch
288+ def attrgot (self :L , k , default = None ):
289+ "Create new `L` with attr `k` (or value `k` for dicts) of all `items`."
290+ return self .map (lambda o : o .get (k ,default ) if isinstance (o , dict ) else nested_attr (o ,k ,default ))
291+
292+ # %% ../nbs/02_foundation.ipynb
293+ @patch
294+ def sorted (self :L , key = None , reverse = False , cmp = None , ** kwargs ):
295+ "New `L` sorted by `key`, using `sort_ex`. If key is str use `attrgetter`; if int use `itemgetter`"
296+ return self ._new (sorted_ex (self , key = key , reverse = reverse , cmp = cmp , ** kwargs ))
297+
298+ # %% ../nbs/02_foundation.ipynb
299+ @patch
300+ def concat (self :L ):
301+ "Concatenate all elements of list"
302+ return self ._new (itertools .chain .from_iterable (self .map (L )))
303+
304+ # %% ../nbs/02_foundation.ipynb
305+ @patch
306+ def copy (self :L ):
307+ "Same as `list.copy`, but returns an `L`"
308+ return self ._new (self .items .copy ())
309+
310+ # %% ../nbs/02_foundation.ipynb
311+ @patch
312+ def cycle (self :L ):
313+ "Same as `itertools.cycle`"
314+ return cycle (self )
315+
316+ # %% ../nbs/02_foundation.ipynb
317+ @patch
318+ def shuffle (self :L ):
319+ "Same as `random.shuffle`, but not inplace"
320+ it = copy (self .items )
321+ random .shuffle (it )
322+ return self ._new (it )
323+
324+ # %% ../nbs/02_foundation.ipynb
325+ @patch
326+ def reduce (self :L , f , initial = None ):
327+ "Wrapper for `functools.reduce`"
328+ return reduce (f , self ) if initial is None else reduce (f , self , initial )
329+
330+ # %% ../nbs/02_foundation.ipynb
331+ @patch
332+ def sum (self :L ):
333+ "Sum of the items"
334+ return self .reduce (operator .add , 0 )
335+
336+ # %% ../nbs/02_foundation.ipynb
337+ @patch
338+ def product (self :L ):
339+ "Product of the items"
340+ return self .reduce (operator .mul , 1 )
341+
342+ # %% ../nbs/02_foundation.ipynb
343+ @patch
344+ def map_first (self :L , f = noop , g = noop , * args , ** kwargs ):
345+ "First element of `map_filter`"
346+ return first (self .map (f , * args , ** kwargs ), g )
347+
348+ # %% ../nbs/02_foundation.ipynb
349+ @patch
350+ def setattrs (self :L , attr , val ):
351+ "Call `setattr` on all items"
352+ [setattr (o ,attr ,val ) for o in self ]
353+
252354# %% ../nbs/02_foundation.ipynb
253355def save_config_file (file , d , ** kwargs ):
254356 "Write settings dict to a new config file, or overwrite the existing one."
0 commit comments