-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
531d3ba
commit ac08492
Showing
2 changed files
with
11 additions
and
104 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,118 +1,25 @@ | ||
# recurtools | ||
|
||
So many questions on StackExchange take the form "How do I ... with a nested list?". | ||
Here are some tools and helpers I developed to solve those kinds of problems | ||
A simple library to support working with recursively nested objects. | ||
|
||
**WARNING** This is a 0.x.x version because I am not yet happy with the function naming. Expect the API to change. | ||
v0.4.0 made breaking changes to string handling in `flatten` - see Changelog for more details. | ||
Primarily built around the **`nested`** class which offers `in`, `len`, `index()` and `count()` functionality. | ||
Additionally, the **`flatten()`** function provides the ability to configure behaviour for strings etc. | ||
|
||
Currently standard functionality is to traverse left-to-right as the collection would be output by `print()` | ||
## Installation | ||
|
||
## Getting Started | ||
|
||
Installation `pip install recurtools` | ||
|
||
### flatten | ||
|
||
A generator which will flatten any iterable collection recursively. | ||
|
||
```python | ||
from recurtools import flatten | ||
input = [1,2,[3,4,[5],6],7,[8,9]] | ||
assert [x for x in flatten(input)] == [1,2,3,4,5,6,7,8,9] | ||
``` | ||
|
||
New in 0.3.0: Optional argument `preservestrings` (default: `False`) will not flatten strings: | ||
|
||
```python | ||
from recurtools import flatten | ||
input = ['ab',3,('cd','e')] | ||
assert [x for x in flatten(input, preservestrings=True)] == ['ab',3,'cd','e'] | ||
pip install recurtools | ||
``` | ||
|
||
### nested | ||
## Usage | ||
|
||
A `Container` which implements `lenrecursive`, `countrecursive`, `inrecursive` and `flatten` for `len()`, `.count()`, `in` and `for x in` | ||
|
||
```python | ||
from recurtools import nested | ||
input = [1,2,[3,4,[5],6],7,[8,9]] | ||
nest = nested(input) | ||
|
||
assert len(nest) == 9 | ||
assert 4 in nest | ||
assert 0 not in nest | ||
|
||
out = [x for x in nest] | ||
assert out == [1,2,3,4,5,6,7,8,9] | ||
|
||
nest2 = nested([1,2,[3,2,[5],6],7,[2,9]]) | ||
assert nest2.count(2) == 3 | ||
``` | ||
|
||
### lenrecursive, sumrecursive, countrecursive, inrecursive | ||
|
||
Recursive versions of `sum`, `count`, `in` and `index`. | ||
|
||
Generally these will return a 0 or `None` value rather than raising an `TypeError` or `ValueError` as their nonrecursive brethren do. | ||
`indexrecursive` is an exception and will raise a specific `NotFoundError`. | ||
|
||
They can also cope with situations where some elements in the nested collection are summable / have a length etc. and others do not. | ||
|
||
```python | ||
from recurtools import sumrecursive | ||
assert sumrecursive([1, 2, [3, 4]]) == 10 | ||
assert sumrecursive([1,2.5,[4,"foo"],(5,(0.5,5))]) == 18 | ||
``` | ||
|
||
```python | ||
from recurtools import countrecursive | ||
assert countrecursive([1, 2, [3, 2]],2) == 2 | ||
assert countrecursive(["ab", "b", ["c", "db", ["e","bob"]]],'b') == 5 | ||
``` | ||
|
||
```python | ||
from recurtools import inrecursive | ||
assert inrecursive([1, 2, [3, 2]],3) == True | ||
from recurtools import nested | ||
``` | ||
|
||
```python | ||
from recurtools import indexrecursive | ||
assert indexrecursive([1, 2, [3, 2]],2) == (1,) | ||
assert indexrecursive([1, 2, [3, 2]],3) == (2,0) | ||
assert indexrecursive(["Foo",[1,"Bar"]],"a") == (1,1,1) | ||
|
||
with raises(NotFoundError): | ||
indexrecursive([1, 2, [3, 2]],4) | ||
``` | ||
|
||
### chainanything | ||
|
||
A generator that chains (m)anything(s). | ||
|
||
```python | ||
from recurtools import chainanything | ||
a = [1, 2, 3] | ||
b = "de" | ||
c = 5 | ||
d = [4, 5, 23, 11, 5] | ||
e = ["dg", "kuku"] | ||
assert [x for x in chainanything(a,b,c,d,e)] == [1, 2, 3, "de", 5, 4, 5, 23, 11, 5, "dg", "kuku"] | ||
assert ''.join(map(str,chainanything(a,b,c,d,e))) == "123de54523115dgkuku" | ||
from recurtools import flatten | ||
``` | ||
|
||
preservestrings = False will lead to strings being yielded as individual characters. Default = `True` | ||
recursive = True will recursively flatten container. Default = `False` (Warning: This may change in v1.0.0) | ||
|
||
Note: preservestrings = False, recursive = False will only flatten strings which are not part of another container. | ||
e.g.: 'abc' -> 'a','b','c' but ['ab','cd'] -> 'ab','cd' | ||
|
||
```python | ||
a = [1, 2, 3] | ||
b = "de" | ||
c = 5 | ||
d = [4, 5, 23, 11, 5] | ||
e = ["dg", "kuku"] | ||
assert [x for x in chainanything(a,b,c,d,e, recursive=False, preservestrings=False)] == [1, 2, 3, "d","e", 5, 4, 5, 23, 11, 5, "dg", "kuku"] | ||
assert [x for x in chainanything(a,b,c,d,e, recursive=True, preservestrings=False)] == [1, 2, 3, "d","e", 5, 4, 5, 23, 11, 5, "d","g", "k","u","k","u"] | ||
``` | ||
## Documentation | ||
For full details see [the docs on github.io](https://musicalninjadad.github.io/recurtools/) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters