pyochain 0.5.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of pyochain might be problematic. Click here for more details.

@@ -0,0 +1,195 @@
1
+ from __future__ import annotations
2
+
3
+ from collections.abc import Callable, Iterable
4
+ from functools import partial
5
+ from typing import TYPE_CHECKING, Any
6
+
7
+ import cytoolz as cz
8
+
9
+ from .._core import IterWrapper, SupportsRichComparison
10
+
11
+ if TYPE_CHECKING:
12
+ from ._main import Seq
13
+
14
+
15
+ class BaseEager[T](IterWrapper[T]):
16
+ def sort[U: SupportsRichComparison[Any]](
17
+ self: BaseEager[U], reverse: bool = False, key: Callable[[U], Any] | None = None
18
+ ) -> Seq[U]:
19
+ """
20
+ Sort the elements of the sequence.
21
+
22
+ Note:
23
+ This method must consume the entire iterable to perform the sort.
24
+ The result is a new iterable over the sorted sequence.
25
+
26
+ Args:
27
+ reverse: Whether to sort in descending order. Defaults to False.
28
+ key: Function to extract a comparison key from each element. Defaults to None.
29
+ Example:
30
+ ```python
31
+ >>> import pyochain as pc
32
+ >>> pc.Iter.from_([3, 1, 2]).sort().into(list)
33
+ [1, 2, 3]
34
+
35
+ ```
36
+ """
37
+
38
+ def _sort(data: Iterable[U]) -> list[U]:
39
+ return sorted(data, reverse=reverse, key=key)
40
+
41
+ return self.collect(_sort)
42
+
43
+ def tail(self, n: int) -> Seq[T]:
44
+ """
45
+ Return a tuple of the last n elements.
46
+
47
+ Args:
48
+ n: Number of elements to return.
49
+ Example:
50
+ ```python
51
+ >>> import pyochain as pc
52
+ >>> pc.Iter.from_([1, 2, 3]).tail(2).unwrap()
53
+ (2, 3)
54
+
55
+ ```
56
+ """
57
+ return self.collect(partial(cz.itertoolz.tail, n))
58
+
59
+ def top_n(self, n: int, key: Callable[[T], Any] | None = None) -> Seq[T]:
60
+ """
61
+ Return a tuple of the top-n items according to key.
62
+
63
+ Args:
64
+ n: Number of top elements to return.
65
+ key: Function to extract a comparison key from each element. Defaults to None.
66
+ Example:
67
+ ```python
68
+ >>> import pyochain as pc
69
+ >>> pc.Iter.from_([1, 3, 2]).top_n(2).unwrap()
70
+ (3, 2)
71
+
72
+ ```
73
+ """
74
+ return self.collect(partial(cz.itertoolz.topk, n, key=key))
75
+
76
+ def union(self, *others: Iterable[T]) -> Seq[T]:
77
+ """
78
+ Return the union of this iterable and 'others'.
79
+
80
+ Note:
81
+ This method consumes inner data and removes duplicates.
82
+
83
+ Args:
84
+ *others: Other iterables to include in the union.
85
+ Example:
86
+ ```python
87
+ >>> import pyochain as pc
88
+ >>> pc.Iter.from_([1, 2, 2]).union([2, 3], [4]).iter().sort().unwrap()
89
+ [1, 2, 3, 4]
90
+
91
+ ```
92
+ """
93
+
94
+ def _union(data: Iterable[T]) -> set[T]:
95
+ return set(data).union(*others)
96
+
97
+ return self.collect(_union)
98
+
99
+ def intersection(self, *others: Iterable[T]) -> Seq[T]:
100
+ """
101
+ Return the elements common to this iterable and 'others'.
102
+
103
+ Note:
104
+ This method consumes inner data, unsorts it, and removes duplicates.
105
+
106
+ Args:
107
+ *others: Other iterables to intersect with.
108
+ Example:
109
+ ```python
110
+ >>> import pyochain as pc
111
+ >>> pc.Iter.from_([1, 2, 2]).intersection([2, 3], [2]).unwrap()
112
+ {2}
113
+
114
+ ```
115
+ """
116
+
117
+ def _intersection(data: Iterable[T]) -> set[T]:
118
+ return set(data).intersection(*others)
119
+
120
+ return self.collect(_intersection)
121
+
122
+ def diff_unique(self, *others: Iterable[T]) -> Seq[T]:
123
+ """
124
+ Return the difference of this iterable and 'others'.
125
+ (Elements in 'self' but not in 'others').
126
+
127
+ Note:
128
+ This method consumes inner data, unsorts it, and removes duplicates.
129
+
130
+ Args:
131
+ *others: Other iterables to subtract from this iterable.
132
+ Example:
133
+ ```python
134
+ >>> import pyochain as pc
135
+ >>> pc.Iter.from_([1, 2, 2]).diff_unique([2, 3]).unwrap()
136
+ {1}
137
+
138
+ ```
139
+ """
140
+
141
+ def _difference(data: Iterable[T]) -> set[T]:
142
+ return set(data).difference(*others)
143
+
144
+ return self.collect(_difference)
145
+
146
+ def diff_symmetric(self, *others: Iterable[T]) -> Seq[T]:
147
+ """
148
+ Return the symmetric difference (XOR) of this iterable and 'others'.
149
+
150
+ Note:
151
+ This method consumes inner data, unsorts it, and removes duplicates.
152
+
153
+ Args:
154
+ *others: Other iterables to compute the symmetric difference with.
155
+ Example:
156
+ ```python
157
+ >>> import pyochain as pc
158
+ >>> pc.Iter.from_([1, 2, 2]).diff_symmetric([2, 3]).iter().sort().unwrap()
159
+ [1, 3]
160
+ >>> pc.Iter.from_([1, 2, 3]).diff_symmetric([3, 4, 5]).iter().sort().unwrap()
161
+ [1, 2, 4, 5]
162
+
163
+ ```
164
+ """
165
+
166
+ def _symmetric_difference(data: Iterable[T]) -> set[T]:
167
+ return set(data).symmetric_difference(*others)
168
+
169
+ return self.collect(_symmetric_difference)
170
+
171
+ def most_common(self, n: int | None = None) -> Seq[tuple[T, int]]:
172
+ """
173
+ Return the n most common elements and their counts.
174
+
175
+ If n is None, then all elements are returned.
176
+
177
+ Args:
178
+ n: Number of most common elements to return. Defaults to None (all elements).
179
+
180
+ Example:
181
+ ```python
182
+ >>> import pyochain as pc
183
+ >>> pc.Iter.from_([1, 1, 2, 3, 3, 3]).most_common(2).unwrap()
184
+ [(3, 3), (1, 2)]
185
+
186
+ ```
187
+ """
188
+ from collections import Counter
189
+
190
+ from ._main import Seq
191
+
192
+ def _most_common(data: Iterable[T]) -> list[tuple[T, int]]:
193
+ return Counter(data).most_common(n)
194
+
195
+ return Seq(self.into(_most_common))
@@ -0,0 +1,503 @@
1
+ from __future__ import annotations
2
+
3
+ import itertools
4
+ from collections.abc import Callable, Generator, Iterable, Iterator
5
+ from functools import partial
6
+ from typing import TYPE_CHECKING, Any, TypeGuard
7
+
8
+ import cytoolz as cz
9
+ import more_itertools as mit
10
+
11
+ from .._core import IterWrapper
12
+
13
+ if TYPE_CHECKING:
14
+ from ._main import Iter
15
+
16
+
17
+ class BaseFilter[T](IterWrapper[T]):
18
+ def filter(self, func: Callable[[T], bool]) -> Iter[T]:
19
+ """
20
+ Return an iterator yielding those items of iterable for which function is true.
21
+
22
+ Args:
23
+ func: Function to evaluate each item.
24
+ Example:
25
+ ```python
26
+ >>> import pyochain as pc
27
+ >>> pc.Iter.from_([1, 2, 3]).filter(lambda x: x > 1).into(list)
28
+ [2, 3]
29
+
30
+ ```
31
+ """
32
+
33
+ def _filter(data: Iterable[T]) -> Iterator[T]:
34
+ return (x for x in data if func(x))
35
+
36
+ return self.apply(_filter)
37
+
38
+ def filter_isin(self, values: Iterable[T]) -> Iter[T]:
39
+ """
40
+ Return elements that are in the given values iterable.
41
+
42
+ Args:
43
+ values: Iterable of values to check membership against.
44
+ Example:
45
+ ```python
46
+ >>> import pyochain as pc
47
+ >>> pc.Iter.from_([1, 2, 3, 4]).filter_isin([2, 4, 6]).into(list)
48
+ [2, 4]
49
+
50
+ ```
51
+ """
52
+
53
+ def _filter_isin(data: Iterable[T]) -> Generator[T, None, None]:
54
+ value_set: set[T] = set(values)
55
+ return (x for x in data if x in value_set)
56
+
57
+ return self.apply(_filter_isin)
58
+
59
+ def filter_notin(self, values: Iterable[T]) -> Iter[T]:
60
+ """
61
+ Return elements that are not in the given values iterable.
62
+
63
+ Args:
64
+ values: Iterable of values to exclude.
65
+ Example:
66
+ ```python
67
+ >>> import pyochain as pc
68
+ >>> pc.Iter.from_([1, 2, 3, 4]).filter_notin([2, 4, 6]).into(list)
69
+ [1, 3]
70
+
71
+ ```
72
+ """
73
+
74
+ def _filter_notin(data: Iterable[T]) -> Generator[T, None, None]:
75
+ value_set: set[T] = set(values)
76
+ return (x for x in data if x not in value_set)
77
+
78
+ return self.apply(_filter_notin)
79
+
80
+ def filter_contain(
81
+ self: IterWrapper[str], text: str, format: Callable[[str], str] | None = None
82
+ ) -> Iter[str]:
83
+ """
84
+ Return elements that contain the given text.
85
+
86
+ Optionally, a format function can be provided to preprocess each element before checking for the substring.
87
+ Args:
88
+ text: Substring to check for.
89
+ format: Optional function to preprocess each element before checking. Defaults to None.
90
+ Example:
91
+ ```python
92
+ >>> import pyochain as pc
93
+ >>>
94
+ >>> data = pc.Seq(["apple", "banana", "cherry", "date"])
95
+ >>> data.iter().filter_contain("ana").into(list)
96
+ ['banana']
97
+ >>> data.iter().map(str.upper).filter_contain("ana", str.lower).into(list)
98
+ ['BANANA']
99
+
100
+ ```
101
+ """
102
+
103
+ def _filter_contain(data: Iterable[str]) -> Generator[str, None, None]:
104
+ def _(x: str) -> bool:
105
+ formatted = format(x) if format else x
106
+ return text in formatted
107
+
108
+ return (x for x in data if _(x))
109
+
110
+ return self.apply(_filter_contain)
111
+
112
+ def filter_attr[U](self, attr: str, dtype: type[U] = object) -> Iter[U]:
113
+ """
114
+ Return elements that have the given attribute.
115
+
116
+ The provided dtype is not checked at runtime for performance considerations.
117
+
118
+ Args:
119
+ attr: Name of the attribute to check for.
120
+ dtype: Expected type of the attribute. Defaults to object.
121
+ Example:
122
+ ```python
123
+ >>> import pyochain as pc
124
+ >>> pc.Iter.from_(["hello", "world", 2, 5]).filter_attr("capitalize", str).into(
125
+ ... list
126
+ ... )
127
+ ['hello', 'world']
128
+
129
+ ```
130
+ """
131
+
132
+ def check(data: Iterable[Any]) -> Generator[U, None, None]:
133
+ def _(x: Any) -> TypeGuard[U]:
134
+ return hasattr(x, attr)
135
+
136
+ return (x for x in data if _(x))
137
+
138
+ return self.apply(check)
139
+
140
+ def filter_false(self, func: Callable[[T], bool]) -> Iter[T]:
141
+ """
142
+ Return elements for which func is false.
143
+
144
+ Args:
145
+ func: Function to evaluate each item.
146
+ Example:
147
+ ```python
148
+ >>> import pyochain as pc
149
+ >>> pc.Iter.from_([1, 2, 3]).filter_false(lambda x: x > 1).into(list)
150
+ [1]
151
+
152
+ ```
153
+ """
154
+ return self.apply(partial(itertools.filterfalse, func))
155
+
156
+ def filter_except(
157
+ self, func: Callable[[T], object], *exceptions: type[BaseException]
158
+ ) -> Iter[T]:
159
+ """
160
+ Yield the items from iterable for which the validator function does not raise one of the specified exceptions.
161
+
162
+ Validator is called for each item in iterable.
163
+
164
+ It should be a function that accepts one argument and raises an exception if that item is not valid.
165
+
166
+ If an exception other than one given by exceptions is raised by validator, it is raised like normal.
167
+
168
+ Args:
169
+ func: Validator function to apply to each item.
170
+ exceptions: Exceptions to catch and ignore.
171
+ Example:
172
+ ```python
173
+ >>> import pyochain as pc
174
+ >>> iterable = ["1", "2", "three", "4", None]
175
+ >>> pc.Iter.from_(iterable).filter_except(int, ValueError, TypeError).into(list)
176
+ ['1', '2', '4']
177
+
178
+ ```
179
+ """
180
+
181
+ def _filter_except(data: Iterable[T]) -> Iterator[T]:
182
+ return mit.filter_except(func, data, *exceptions)
183
+
184
+ return self.apply(_filter_except)
185
+
186
+ def take_while(self, predicate: Callable[[T], bool]) -> Iter[T]:
187
+ """
188
+ Take items while predicate holds.
189
+
190
+ Args:
191
+ predicate: Function to evaluate each item.
192
+ Example:
193
+ ```python
194
+ >>> import pyochain as pc
195
+ >>> pc.Iter.from_([1, 2, 0]).take_while(lambda x: x > 0).into(list)
196
+ [1, 2]
197
+
198
+ ```
199
+ """
200
+ return self.apply(partial(itertools.takewhile, predicate))
201
+
202
+ def skip_while(self, predicate: Callable[[T], bool]) -> Iter[T]:
203
+ """
204
+ Drop items while predicate holds.
205
+
206
+ Args:
207
+ predicate: Function to evaluate each item.
208
+ Example:
209
+ ```python
210
+ >>> import pyochain as pc
211
+ >>> pc.Iter.from_([1, 2, 0]).skip_while(lambda x: x > 0).into(list)
212
+ [0]
213
+
214
+ ```
215
+ """
216
+ return self.apply(partial(itertools.dropwhile, predicate))
217
+
218
+ def compress(self, *selectors: bool) -> Iter[T]:
219
+ """
220
+ Filter elements using a boolean selector iterable.
221
+
222
+ Args:
223
+ selectors: Boolean values indicating which elements to keep.
224
+ Example:
225
+ ```python
226
+ >>> import pyochain as pc
227
+ >>> pc.Iter.from_("ABCDEF").compress(1, 0, 1, 0, 1, 1).into(list)
228
+ ['A', 'C', 'E', 'F']
229
+
230
+ ```
231
+ """
232
+ return self.apply(itertools.compress, selectors)
233
+
234
+ def unique(self, key: Callable[[T], Any] | None = None) -> Iter[T]:
235
+ """
236
+ Return only unique elements of the iterable.
237
+
238
+ Args:
239
+ key: Function to transform items before comparison. Defaults to None.
240
+ Example:
241
+ ```python
242
+ >>> import pyochain as pc
243
+ >>> pc.Iter.from_([1, 2, 3]).unique().into(list)
244
+ [1, 2, 3]
245
+ >>> pc.Iter.from_([1, 2, 1, 3]).unique().into(list)
246
+ [1, 2, 3]
247
+
248
+ ```
249
+ Uniqueness can be defined by key keyword
250
+ ```python
251
+ >>> pc.Iter.from_(["cat", "mouse", "dog", "hen"]).unique(key=len).into(list)
252
+ ['cat', 'mouse']
253
+
254
+ ```
255
+ """
256
+ return self.apply(cz.itertoolz.unique, key=key)
257
+
258
+ def take(self, n: int) -> Iter[T]:
259
+ """
260
+ Creates an iterator that yields the first n elements, or fewer if the underlying iterator ends sooner.
261
+
262
+ `Iter.take(n)` yields elements until n elements are yielded or the end of the iterator is reached (whichever happens first).
263
+
264
+ The returned iterator is either:
265
+
266
+ - A prefix of length n if the original iterator contains at least n elements
267
+ - All of the (fewer than n) elements of the original iterator if it contains fewer than n elements.
268
+
269
+ Args:
270
+ n: Number of elements to take.
271
+ Example:
272
+ ```python
273
+ >>> import pyochain as pc
274
+ >>> data = [1, 2, 3]
275
+ >>> pc.Iter.from_(data).take(2).into(list)
276
+ [1, 2]
277
+ >>> pc.Iter.from_(data).take(5).into(list)
278
+ [1, 2, 3]
279
+
280
+ ```
281
+ """
282
+
283
+ return self.apply(partial(cz.itertoolz.take, n))
284
+
285
+ def skip(self, n: int) -> Iter[T]:
286
+ """
287
+ Drop first n elements.
288
+
289
+ Args:
290
+ n: Number of elements to skip.
291
+ Example:
292
+ ```python
293
+ >>> import pyochain as pc
294
+ >>> pc.Iter.from_([1, 2, 3]).skip(1).into(list)
295
+ [2, 3]
296
+
297
+ ```
298
+ """
299
+ return self.apply(partial(cz.itertoolz.drop, n))
300
+
301
+ def unique_justseen(self, key: Callable[[T], Any] | None = None) -> Iter[T]:
302
+ """
303
+ Yields elements in order, ignoring serial duplicates.
304
+
305
+ Args:
306
+ key: Function to transform items before comparison. Defaults to None.
307
+ Example:
308
+ ```python
309
+ >>> import pyochain as pc
310
+ >>> pc.Iter.from_("AAAABBBCCDAABBB").unique_justseen().into(list)
311
+ ['A', 'B', 'C', 'D', 'A', 'B']
312
+ >>> pc.Iter.from_("ABBCcAD").unique_justseen(str.lower).into(list)
313
+ ['A', 'B', 'C', 'A', 'D']
314
+
315
+ ```
316
+ """
317
+ return self.apply(mit.unique_justseen, key=key)
318
+
319
+ def unique_in_window(
320
+ self, n: int, key: Callable[[T], Any] | None = None
321
+ ) -> Iter[T]:
322
+ """
323
+ Yield the items from iterable that haven't been seen recently.
324
+
325
+ The items in iterable must be hashable.
326
+ Args:
327
+ n: Size of the lookback window.
328
+ key: Function to transform items before comparison. Defaults to None.
329
+ Example:
330
+ ```python
331
+ >>> import pyochain as pc
332
+ >>> iterable = [0, 1, 0, 2, 3, 0]
333
+ >>> n = 3
334
+ >>> pc.Iter.from_(iterable).unique_in_window(n).into(list)
335
+ [0, 1, 2, 3, 0]
336
+
337
+ ```
338
+ The key function, if provided, will be used to determine uniqueness:
339
+ ```python
340
+ >>> pc.Iter.from_("abAcda").unique_in_window(3, key=str.lower).into(list)
341
+ ['a', 'b', 'c', 'd', 'a']
342
+
343
+ ```
344
+ """
345
+ return self.apply(mit.unique_in_window, n, key=key)
346
+
347
+ def extract(self, indices: Iterable[int]) -> Iter[T]:
348
+ """
349
+ Yield values at the specified indices.
350
+
351
+ - The iterable is consumed lazily and can be infinite.
352
+ - The indices are consumed immediately and must be finite.
353
+ - Raises IndexError if an index lies beyond the iterable.
354
+ - Raises ValueError for negative indices.
355
+
356
+ Args:
357
+ indices: Iterable of indices to extract values from.
358
+ Example:
359
+ ```python
360
+ >>> import pyochain as pc
361
+ >>> text = "abcdefghijklmnopqrstuvwxyz"
362
+ >>> pc.Iter.from_(text).extract([7, 4, 11, 11, 14]).into(list)
363
+ ['h', 'e', 'l', 'l', 'o']
364
+
365
+ ```
366
+ """
367
+ return self.apply(mit.extract, indices)
368
+
369
+ def every(self, index: int) -> Iter[T]:
370
+ """
371
+ Return every nth item starting from first.
372
+
373
+ Args:
374
+ index: Step size for selecting items.
375
+ Example:
376
+ ```python
377
+ >>> import pyochain as pc
378
+ >>> pc.Iter.from_([10, 20, 30, 40]).every(2).into(list)
379
+ [10, 30]
380
+
381
+ ```
382
+ """
383
+ return self.apply(partial(cz.itertoolz.take_nth, index))
384
+
385
+ def slice(self, start: int | None = None, stop: int | None = None) -> Iter[T]:
386
+ """
387
+ Return a slice of the iterable.
388
+
389
+ Args:
390
+ start: Starting index of the slice. Defaults to None.
391
+ stop: Ending index of the slice. Defaults to None.
392
+ Example:
393
+ ```python
394
+ >>> import pyochain as pc
395
+ >>> pc.Iter.from_([1, 2, 3, 4, 5]).slice(1, 4).into(list)
396
+ [2, 3, 4]
397
+
398
+ ```
399
+ """
400
+
401
+ def _slice(data: Iterable[T]) -> Iterator[T]:
402
+ return itertools.islice(data, start, stop)
403
+
404
+ return self.apply(_slice)
405
+
406
+ def filter_subclass[U: type[Any], R](
407
+ self: IterWrapper[U], parent: type[R], keep_parent: bool = True
408
+ ) -> Iter[type[R]]:
409
+ """
410
+ Return elements that are subclasses of the given class, optionally excluding the parent class itself.
411
+
412
+ Args:
413
+ parent: Parent class to check against.
414
+ keep_parent: Whether to include the parent class itself. Defaults to True.
415
+ Example:
416
+ ```python
417
+ >>> import pyochain as pc
418
+ >>> class A:
419
+ ... pass
420
+ >>> class B(A):
421
+ ... pass
422
+ >>> class C:
423
+ ... pass
424
+ >>> def name(cls: type[Any]) -> str:
425
+ ... return cls.__name__
426
+ >>>
427
+ >>> data = pc.Seq([A, B, C])
428
+ >>> data.iter().filter_subclass(A).map(name).into(list)
429
+ ['A', 'B']
430
+ >>> data.iter().filter_subclass(A, keep_parent=False).map(name).into(list)
431
+ ['B']
432
+
433
+ ```
434
+ """
435
+
436
+ def _filter_subclass(
437
+ data: Iterable[type[Any]],
438
+ ) -> Generator[type[R], None, None]:
439
+ if keep_parent:
440
+ return (x for x in data if issubclass(x, parent))
441
+ else:
442
+ return (x for x in data if issubclass(x, parent) and x is not parent)
443
+
444
+ return self.apply(_filter_subclass)
445
+
446
+ def filter_type[R](self, typ: type[R]) -> Iter[R]:
447
+ """
448
+ Return elements that are instances of the given type.
449
+
450
+ Args:
451
+ typ: Type to check against.
452
+ Example:
453
+ ```python
454
+ >>> import pyochain as pc
455
+ >>> pc.Iter.from_([1, "two", 3.0, "four", 5]).filter_type(int).into(list)
456
+ [1, 5]
457
+
458
+ ```
459
+ """
460
+
461
+ def _filter_type(data: Iterable[T]) -> Generator[R, None, None]:
462
+ return (x for x in data if isinstance(x, typ))
463
+
464
+ return self.apply(_filter_type)
465
+
466
+ def filter_callable(self) -> Iter[Callable[..., Any]]:
467
+ """
468
+ Return only elements that are callable.
469
+
470
+ Example:
471
+ ```python
472
+ >>> import pyochain as pc
473
+ >>> pc.Iter.from_([len, 42, str, None, list]).filter_callable().into(list)
474
+ [<built-in function len>, <class 'str'>, <class 'list'>]
475
+
476
+ ```
477
+ """
478
+
479
+ def _filter_callable(
480
+ data: Iterable[T],
481
+ ) -> Generator[Callable[..., Any], None, None]:
482
+ return (x for x in data if callable(x))
483
+
484
+ return self.apply(_filter_callable)
485
+
486
+ def filter_map[R](self, func: Callable[[T], R]) -> Iter[R]:
487
+ """
488
+ Apply func to every element of iterable, yielding only those which are not None.
489
+
490
+ Args:
491
+ func: Function to apply to each item.
492
+ Example:
493
+ ```python
494
+ >>> import pyochain as pc
495
+ >>> def to_int(s: str) -> int | None:
496
+ ... return int(s) if s.isnumeric() else None
497
+ >>> elems = ["1", "a", "2", "b", "3"]
498
+ >>> pc.Iter.from_(elems).filter_map(to_int).into(list)
499
+ [1, 2, 3]
500
+
501
+ ```
502
+ """
503
+ return self.apply(partial(mit.filter_map, func))