Clojure-like utilities
Project description
clj
clj is a collection of functions to work with lazy iterators in Python.
It’s a module for those times when you did too much Clojure and came back to Python wondering where are all these
distinct, drop-while, cycle, first, etc.
The library is oriented toward laziness and performance. Functions are implemented with as little overhead as possible.
Install
pip install clj
Usage
Example
;; Clojure
(println (count (distinct (filter even? (map inc coll)))))
# Python
from clj import count, distinct, filter, inc, map
even = lambda e: ~e&1
print(count(distinct(filter(even, map(inc, coll)))))
Note that count() works on both sequences in generators; in the latter case
it doesn’t load everything in memory like e.g. len(list(g)) would do.
Core Ideas
- Lazy by default. All functions should work on arbitrary iterators and return generators.
- This is Python. We keep Python’s semantics instead of trying to reproduce
Clojure in Python (e.g.
0and[]are logically true in Clojure but false in Python;Noneis not equivalent to an empty collection). - Don’t Reinvent the Wheel. We don’t reimplement built-in functions
unless they miss something:
rangebecause it can’t be called without argument to yield an infinite sequence;mapandfilterin Python 2 because they aren’t lazy.
Support
The general naming scheme is: use underscores instead of hyphens; start the
function with is_ if its Clojure counterparts ends with a ?.
Sequences
We aim to implement all Clojure functions that operate on sequences (see the list here). They all work on iterables and return generators by default (Python’s closest equivalent of lazy seqs). We don’t support transducers.
| Clojure | clj |
Comment |
|---|---|---|
distinct |
distinct |
|
filter |
filter |
|
remove |
remove |
|
keep |
keep |
|
keep-indexed |
keep_indexed |
|
cons |
cons |
|
concat |
concat |
Equivalent to itertools.chain. |
lazy-cat |
- | Use Python’s itertools.chain. |
mapcat |
mapcat |
|
cycle |
cycle |
|
interleave |
interleave |
|
interpose |
interpose |
|
rest |
rest |
|
next |
- | Use rest. |
fnext |
- | Use second. |
nnext |
- | Use rest(rest(…)) |
drop |
drop |
|
drop-while |
drop_while |
Equivalent to itertools.dropwhile. |
nthnext |
- | Use drop. |
take |
take |
|
take-nth |
take_nth |
|
take-while |
take_while |
Equivalent to itertools.takewhile. |
butlast |
butlast |
|
drop-last |
drop_last |
|
flatten |
flatten |
|
reverse |
reverse |
|
sort |
- | Use Python’s built-in sort. |
sort-by |
- | Use sort(…, key=your_function). |
shuffle |
shuffle |
|
split-at |
split_at |
|
split-with |
split_with |
|
partition |
partition |
(partition n step pad coll) becomes partition(coll, n, step, pad). The support for a step different from n is not implemented for now. |
partition-all |
||
partition-by |
||
map |
map |
|
pmap |
- | |
replace |
replace |
|
reductions |
reductions |
(reductions f i c) becomes reductions(f, c, i). |
map-indexed |
map_indexed |
|
seque |
- | |
first |
first |
|
ffirst |
ffirst |
|
nfirst |
nfirst |
|
second |
second |
|
nth |
nth |
|
last |
last |
|
rand-nth |
- | Use Python’s random.choice. |
zipmap |
zipmap |
|
into |
- | |
reduce |
- | Use Python’s built-in reduce. |
set |
- | Use Python’s set. |
vec |
- | Use Python’s list. |
into-array |
- | Use Python’s list. |
to-array-2d |
- | |
frequencies |
- | Use Python’s collections.Counter. |
group-by |
group_by |
|
apply |
- | Use the f(*args) construct. |
not-empty |
- | |
some |
some |
|
seq? |
is_seq |
|
every? |
every |
|
not-every? |
not_every |
|
not-any? |
not_any |
|
empty? |
- | |
empty |
empty |
|
doseq |
- | Use for … in. |
dorun |
dorun |
|
doall |
- | Use Python’s list. |
realized? |
- | |
seq |
- | |
vals |
- | Use Python’s dict.values. |
keys |
- | Use Python’s dict.keys. |
rseq |
- | |
subseq |
||
rsubseq |
||
repeatedly |
repeatedly |
|
iterate |
iterate |
|
repeat |
repeat |
(repeat n x) becomes repeat(x, n). Equivalent to itertools.repeat. |
range |
range |
Prefer Python’s range for everything but infinite generators. |
line-seq |
- | Loop over an io.BufferedReader. |
resultset-seq |
- | |
re-seq |
- | Use Python’s re.finditer. |
tree-seq |
tree_seq |
|
file-seq |
- | Use Python’s os.walk. |
xml-seq |
- | |
iterator-seq |
- | |
enumeration-seq |
- | |
hash-map |
- | Use Python’s dict. |
array-map |
- | Use Python’s dict. |
sorted-map |
- | Use collections.OrderedDict. |
sorted-map-by |
||
hash-set |
- | Use Python’s set. |
set |
- | Use Python’s set. |
sorted-set |
||
sorted-set-by |
||
dedupe |
dedupe |
We also implemented count, which uses Python’s len when possible and
fallbacks on a for loop for other cases.
Functions
We also provide miscellaneous functions as well as functions that work on functions.
| Clojure | clj |
Comment |
|---|---|---|
identity |
identity |
|
partial |
- | Use Python’s functools.partial |
comp |
comp |
|
complement |
complement |
|
constantly |
constantly |
|
juxt |
juxt |
|
distinct? |
is_distinct |
| Clojure | clj |
Comment |
|---|---|---|
inc |
inc |
|
dec |
dec |
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file clj-0.1.6.tar.gz.
File metadata
- Download URL: clj-0.1.6.tar.gz
- Upload date:
- Size: 14.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/3.4.1 importlib_metadata/3.10.0 pkginfo/1.7.0 requests/2.25.0 requests-toolbelt/0.9.1 tqdm/4.60.0 CPython/3.9.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0d6655bbf14fa26efcd5135eedfa71b574aaf85678c621122a6e318bde609a0e
|
|
| MD5 |
42796018f54006947586de59a68ef972
|
|
| BLAKE2b-256 |
b97a2d94f89e6c2dc1071f8e8524366982da87f495701ada2837a757fe71dbca
|
File details
Details for the file clj-0.1.6-py3-none-any.whl.
File metadata
- Download URL: clj-0.1.6-py3-none-any.whl
- Upload date:
- Size: 10.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/3.4.1 importlib_metadata/3.10.0 pkginfo/1.7.0 requests/2.25.0 requests-toolbelt/0.9.1 tqdm/4.60.0 CPython/3.9.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
cf4955d9ae1b9682a8769714654383881555548d24ebfd1d69cd50e8119c3690
|
|
| MD5 |
8a4231732d689633de82f38a7fbef1a8
|
|
| BLAKE2b-256 |
627131bb58db217383a59367b04d9c46e98636367e039cd3df785b7133ce1ae9
|