Fork of 'iterchain', Chitter allows you to chain iters.
Project description
Chitter: my take on iterator chaining for Python
Introduction
Chitter is a fork Evelyn H's iterchain package, but made to be mine. Anyway, this package makes working with iterators in python more ergonomic by allowing you to chain methods on them (that's easier to read).
Similarly to Evelyn's this package's design is inspired by the Rust iterators, stuff from python's own standard library (itertools).
Installation
With Poetry:
poetry add chitter
With Pip:
pip install chitter
For the development version:
git clone https://github.com/brunofauth/chitter.git
cd ./chitter/
poetry install
Everything below this line comes straight from iterchain
's docs, so keep that in mind while reading...
Why would I need this?
Say we want to know the sum of all the squares of even numbers up to 100.
How can we do this?
Let's try some straightforward, procedural Python:
>>> total = 0
>>> for i in range(100):
... if i % 2 is 0:
... total += i ** 2
...
>>> total
161700
This works, but if you read this for the first time it can take a bit of effort to figure out what's happening, especially in slightly less trivial cases. So, how about we use iterators instead?
Well, let's see:
>>> sum(i**2 for i in range(100) if i % 2 is 0)
161700
That's pretty nice! Much shorter, and much easier to understand. But there's a
problem, this pattern only works for relatively simple manipulations. In those
cases you could try using the python map
and filter
builtins (and the
slightly more hidden functools.reduce
). They let you construct more complex
processing chains.
Let's rewrite our iterator to use those functions instead:
>>> sum(map(lambda x: x**2, filter(lambda x: x % 2 is 0, range(100))))
161700
Okay, now that is a mess... I don't know about you, but it would take me
quite a while to unravel what's happening here. The problem is that the whole
expression is inside out. The filter
gets applied first, but it's hidden in
the middle of the expression, and the sum
gets applied last but it is all the
way in the front. Makes no sense...
So, how can we improve on this? iterchain
of course!
(you probably saw this coming already)
So, let's see how it looks using iterchain
:
>>> import iterchain
>>> (iterchain.count(stop=100)
... .filter(lambda x: x % 2 is 0)
... .map(lambda x: x**2)
... .sum())
161700
Isn't this much better? The operations are listed in the order that they're
executed, are clearly separated, and you can have as few or as many operations
as you want. This is why you should use iterchain
!
Generators
iterchain
also provides handy methods that let you build new Iterator
instances from scratch. These are contained in the iterchain.generators
sub-module, but they're also accessible directly from the iterchain
module,
which is the preferred way of using them.
For example:
>>> import iterchain
>>> iterchain.count().take(4).map(lambda x: x**2).to_list()
[0, 1, 4, 9]
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
File details
Details for the file chitter-0.2.1.tar.gz
.
File metadata
- Download URL: chitter-0.2.1.tar.gz
- Upload date:
- Size: 17.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/4.0.2 CPython/3.11.6
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | b493f8853c9545661d3caa202efd37a957e5757c17fba77524a0f5e0a73d0ab6 |
|
MD5 | 75f15fedc1af08291edd826502f47cd5 |
|
BLAKE2b-256 | ae75a5ef46ba292428707675a034a57767687bb619a2134280f09f5954985084 |