Skip to content

Commit 6348612

Browse files
committed
fixes #97
1 parent 9e95062 commit 6348612

File tree

5 files changed

+155
-58
lines changed

5 files changed

+155
-58
lines changed

fastcore/_nbdev.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
"delegate_attr": "01_foundation.ipynb",
4242
"bind": "01_foundation.ipynb",
4343
"listable_types": "01_foundation.ipynb",
44+
"first": "01_foundation.ipynb",
4445
"CollBase": "01_foundation.ipynb",
4546
"L": "01_foundation.ipynb",
4647
"L.__signature__": "01_foundation.ipynb",
@@ -72,7 +73,6 @@
7273
"is_listy": "02_utils.ipynb",
7374
"range_of": "02_utils.ipynb",
7475
"groupby": "02_utils.ipynb",
75-
"first": "02_utils.ipynb",
7676
"last_index": "02_utils.ipynb",
7777
"shufflish": "02_utils.ipynb",
7878
"IterLen": "02_utils.ipynb",

fastcore/foundation.py

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
__all__ = ['defaults', 'copy_func', 'patch_to', 'patch', 'patch_property', 'add_docs', 'docs', 'custom_dir', 'arg0',
44
'arg1', 'arg2', 'arg3', 'arg4', 'coll_repr', 'is_bool', 'mask2idxs', 'cycle', 'zip_cycle', 'is_indexer',
5-
'negate_func', 'GetAttr', 'delegate_attr', 'bind', 'listable_types', 'CollBase', 'L']
5+
'negate_func', 'GetAttr', 'delegate_attr', 'bind', 'listable_types', 'first', 'CollBase', 'L']
66

77
# Cell
88
from .imports import *
@@ -181,6 +181,12 @@ def __call__(self, *args, **kwargs):
181181
# Cell
182182
listable_types = typing.Collection,Generator,map,filter,zip
183183

184+
# Cell
185+
def first(x):
186+
"First element of `x`, or None if missing"
187+
try: return next(iter(x))
188+
except StopIteration: return None
189+
184190
# Cell
185191
class CollBase:
186192
"Base class for composing a list of `items`"
@@ -265,16 +271,20 @@ def range(cls, a, b=None, step=None):
265271
if is_coll(a): a = len(a)
266272
return cls(range(a,b,step) if step is not None else range(a,b) if b is not None else range(a))
267273

268-
def map(self, f, *args, **kwargs):
274+
def map(self, f, *args, gen=False, **kwargs):
269275
g = (bind(f,*args,**kwargs) if callable(f)
270276
else f.format if isinstance(f,str)
271277
else f.__getitem__)
272-
return self._new(map(g, self))
278+
res = map(g, self)
279+
if gen: return res
280+
return self._new(res)
273281

274-
def filter(self, f, negate=False, **kwargs):
282+
def filter(self, f=noop, negate=False, gen=False, **kwargs):
275283
if kwargs: f = partial(f,**kwargs)
276284
if negate: f = negate_func(f)
277-
return self._new(filter(f, self))
285+
res = filter(f, self)
286+
if gen: return res
287+
return self._new(res)
278288

279289
def argwhere(self, f, negate=False, **kwargs):
280290
if kwargs: f = partial(f,**kwargs)
@@ -291,7 +301,13 @@ def itemgot(self, *idxs):
291301

292302
def attrgot(self, k, default=None): return self.map(lambda o: o.get(k,default) if isinstance(o, dict) else getattr(o,k,default))
293303
def cycle(self): return cycle(self)
294-
def map_dict(self, f=noop, *args, **kwargs): return {k:f(k, *args,**kwargs) for k in self}
304+
def map_dict(self, f=noop, *args, gen=False, **kwargs): return {k:f(k, *args,**kwargs) for k in self}
305+
def map_filter(self, f=noop, g=noop, *args, gen=False, **kwargs):
306+
res = filter(g, self.map(f, *args, gen=gen, **kwargs))
307+
if gen: return res
308+
return self._new(res)
309+
def map_first(self, f=noop, g=noop, *args, **kwargs): return first(self.map_filter(f, g, *args, gen=False, **kwargs))
310+
295311
def starmap(self, f, *args, **kwargs): return self._new(itertools.starmap(partial(f,*args,**kwargs), self))
296312
def zip(self, cycled=False): return self._new((zip_cycle if cycled else zip)(*self))
297313
def zipwith(self, *rest, cycled=False): return self._new([self, *rest]).zip(cycled=cycled)
@@ -329,6 +345,8 @@ def product(self): return self.reduce(operator.mul)
329345
filter="Create new `L` filtered by predicate `f`, passing `args` and `kwargs` to `f`",
330346
argwhere="Like `filter`, but return indices for matching items",
331347
map="Create new `L` with `f` applied to all `items`, passing `args` and `kwargs` to `f`",
348+
map_filter="Same as `map` with `f` followed by `filter` with `g`",
349+
map_first="First element of `map_filter`",
332350
map_dict="Like `map`, but creates a dict from `items` to function results",
333351
starmap="Like `map`, but use `itertools.starmap`",
334352
itemgot="Create new `L` with item `idx` of all `items`",

fastcore/utils.py

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
__all__ = ['ifnone', 'maybe_attr', 'basic_repr', 'get_class', 'mk_class', 'wrap_class', 'ignore_exceptions', 'dict2obj',
44
'store_attr', 'attrdict', 'properties', 'camel2snake', 'snake2camel', 'class2attr', 'hasattrs', 'ShowPrint',
55
'Int', 'Str', 'Float', 'tuplify', 'detuplify', 'replicate', 'uniqueify', 'setify', 'merge', 'is_listy',
6-
'range_of', 'groupby', 'first', 'last_index', 'shufflish', 'IterLen', 'ReindexCollection', 'num_methods',
6+
'range_of', 'groupby', 'last_index', 'shufflish', 'IterLen', 'ReindexCollection', 'num_methods',
77
'rnum_methods', 'inum_methods', 'fastuple', 'Inf', 'in_', 'lt', 'gt', 'le', 'ge', 'eq', 'ne', 'add', 'sub',
88
'mul', 'truediv', 'is_', 'is_not', 'in_', 'true', 'stop', 'gen', 'chunked', 'trace', 'compose', 'maps',
99
'partialler', 'mapped', 'instantiate', 'using_attr', 'Self', 'Self', 'remove_patches_path', 'bunzip',
@@ -217,12 +217,6 @@ def groupby(x, key):
217217
for o in x: res.setdefault(key(o), []).append(o)
218218
return res
219219

220-
# Cell
221-
def first(x):
222-
"First element of `x`, or None if missing"
223-
try: return next(iter(x))
224-
except StopIteration: return None
225-
226220
# Cell
227221
def last_index(x, o):
228222
"Finds the last index of occurence of `x` in `o` (returns -1 if no occurence)"

0 commit comments

Comments
 (0)