Skip to main content

python_ramda

This is a repo try to copy https://github.com/ramda/ramda in python.

linting: pylint PyPI version Python Versions codecov

install

For whom wants to use this package.

> pip install python-ramda
> pip install python-ramda -U # get the latest

Usage

>>> from ramda import curry
>>> def sum(a, b, c): return a + b + c
>>> curry(sum)(1)(2, 3)
6
>>> import ramda as R # similar to ramda syntax
>>> def sum(a, b, c): return a + b + c
>>> R.curry(sum)(1)(2, 3)
6

Doc

Because the usage of python_ramda is almostly same to ramda, so we don't create any extra doc.

If you feel any behaviour is different from what is should be in ramda, please check below CheckList for more details.

Contribute

For whom wants to contribute to this repo.

$ pip install -U pylint
# see: https://pre-commit.com/ for more details
$ pre-commit install # please install hooks first

Checkout new branch from main branch directly and create PR.

CheckList

Functions supported now.

  • 0.1.2 __
  • 0.1.2 add
# different from ramda
R.add(None, None) # float('nan)
R.add(date(1,2,3), date(1,2,3)) # float('nan)
  • addIndex
  • 0.1.2 adjust
  • 0.1.2 all
    • Transducer part is not fully tested.
  • allPass
  • 0.1.2 always
  • 0.1.2 And (and is a keyword in python)
  • andThen
  • 0.1.2 any
  • anyPass
  • ap
  • aperture
  • 0.1.2 append
  • apply
  • applySpec
  • applyTo
  • ascend
  • assoc
  • assocPath
  • 0.2.0 binary
  • bind
  • both
  • call
  • chain
  • clamp
  • 0.1.2 clone

we are simply using python copy module So with no specific reason, we suggest you to use python origin copy module as your first choice.

class Obj:
  def __init__(self, x):
    self.value = x
obj = Obj(42)
clone = R.clone(obj)
obj == clone # False, obj and clone have different references
isinstance(clone, Obj) # True

class Obj:
  def __init__(self, x):
    self.value = x

  def __eq__(self, other):
    return self.value == other.value
obj = Obj(42)
clone = R.clone(obj)
obj == clone # True, if Obj override __eq__ function
isinstance(clone, Obj) # True
  • collectBy
  • 0.1.2 comparator
  • complement
  • 0.1.2 compose
  • composeWith
  • 0.1.2 concat
  • cond
  • construct
  • constructN
  • 0.1.4 converge
  • count
  • 0.1.2 countBy
  • 0.1.2 curry
  • 0.1.2 curryN
  • dec
  • defaultTo
  • descend
  • 0.1.2 difference
  • 0.1.2 differenceWith
  • dissoc
  • dissocPath
  • 0.1.2 divide
  • 0.1.2 drop
  • dropLast
  • dropLastWhile
  • dropRepeats
  • dropRepeatsWith
  • dropWhile
  • either
  • 0.1.2 empty
# We don't support empty object in python
class Obj:
  def __init__(self, value):
    self.value = value
o = Obj(42)
o == R.empty(o) # True, we will return the original cloned object

What we support for now:

  1. dict()
  2. set()
  3. list()
  4. str()
  5. any instance with empty() method
  6. any instance with 'fantasy-land/empty' property
  • endsWith
  • eqBy
  • 0.1.2 eqProps
# works for both dict and object
class Obj:
  def __init__(self, v):
    self.v = v
obj1 = Obj(1)
obj2 = Obj(1)
R.eqProps('v', obj1, obj2) # True
R.eqProps('v', {'v': 1}, {'v': 1}) # True
  • 0.1.2 equals
R.equals(float('nan'), float('nan')) # True
  • evolve
  • 0.1.2 F
  • 0.1.2 filter
  • 0.1.2 find
  • 0.1.4 findIndex
  • 0.1.4 findLast
  • 0.1.4 findLastIndex
  • 0.1.2 flatten
  • 0.1.2 flip
  • 0.1.4 forEach
  • forEachObjIndexed
  • fromPairs
  • 0.1.2 groupBy
  • groupWith
  • 0.1.2 gt
  • 0.1.2 gte
  • has
  • hasIn
  • hasPath
  • 0.1.2 head
  • identical
  • 0.1.2 identity
  • ifElse
  • inc
  • includes
  • indexBy
  • 0.1.2 indexOf
  • init
  • innerJoin
  • insert
  • insertAll
  • 0.1.2 intersection
  • intersperse
  • 0.1.2 into
  • invert
  • invertObj
  • 0.1.2 invoker
  • is
  • 0.1.2 isEmpty
class Obj:
  pass
# Any custom object will be treated as non-empty
R.isEmpty(Obj()) # False
R.isEmpty(None) # False
  • isNil
  • 0.1.2 join
  • 0.1.4 juxt
  • 0.1.2 keys
# When using R.keys(obj) and obj is a class instance, we use obj.__dict__ as keys.
class A:
  c = 'not included'
  def __init__(self):
    self.a = 1
    self.b = 2
a = A()
R.keys(a) # ['a', 'b']
# keys include super class attributes
class A:
  def __init__(self, a):
    self.a = a

class B(A):
  def __init__(self, a, b):
    super().__init__(a)
    self.b = b

class C(A):
  def __init__(self, c):
    self.c = c

a = A(1)
b = B(2, 3)
c = C(4)
R.keys(a) # ['a']
R.keys(b) # ['a', 'b']
R.keys(c) # ['c'], because c does not call super().__init__()

# For normal dict
R.keys({'a': 1, 'b': 2}) # ['a', 'b']
  • 0.2.0 keysIn

Different from keys, keysIn will return all attributes of the object, including super class attributes and class static variables.

class A:
  a_static = 1
  def __init__(self):
    self.a = 1
class B(A):
  b_static = 2
  def __init__(self, b):
    super().__init__()
    self.b = b

R.keysIn(A()) # ['a_static', 'a']
R.keysIn(B(2)) # ['a_static', 'a', 'b_static', 'b']

# For normal dict
R.keysIn({'a': 1, 'b': 2}) # ['a', 'b']
  • 0.1.4 last
  • 0.1.2 lastIndexOf
  • length
  • lens
  • lensIndex
  • lensPath
  • lensProp
  • lift
  • liftN
  • 0.1.2 lt
  • 0.1.2 lte
  • 0.1.2 map
  • mapAccum
  • mapAccumRight
  • mapObjIndexed
  • 0.1.2 match
  • mathMod
  • 0.1.2 Max (max is a keyword in python)

If R.Max(a, b) a and b are with different types, we will compare with str(a) and str(b).

R.Max('A', None) # None, 'A' < 'None'
  • maxBy
  • mean
  • median
  • memoizeWith
  • mergeAll
  • mergeDeepLeft
  • mergeDeepRight
  • mergeDeepWith
  • mergeDeepWithKey
  • mergeLeft
  • mergeRight
  • mergeWith
  • mergeWithKey
  • 0.1.2 Min (min is a keyword in python)

If R.Min(a, b) a and b are with different types, we will compare with str(a) and str(b).

R.Min('A', None) # 'A', 'A' < 'None'
  • minBy
  • modify
  • modifyPath
  • 0.1.4 modulo

Python modulo on negative numbers has different behavior than JS.

5 % -3 # -1
5 % -3 // 2
  • move
  • 0.1.2 multiply
  • 0.2.0 nAry
  • negate
  • none
  • 0.1.2 not
  • 0.1.2 nth
  • nthArg
  • o
  • 0.1.2 objOf
  • of
  • 0.1.2 omit

we support both dict type and object type.

class Obj:
  def __init__(self, v1, v2):
    self.v1 = v1
    self.v2 = v2
obj = Obj(1, 2)
R.omit(['v1'], obj) # {'v2': 2}
R.omit(['v1', 'v3'], obj) # {'v2': 2}
  • on
  • 0.1.2 once
  • 0.1.2 or
  • otherwise
  • over
  • pair
  • partial
  • partialObject
  • partialRight
  • 0.1.4 partition
  • 0.1.2 path
  • pathEq
  • pathOr
  • 0.1.2 paths
  • pathSatisfies
  • 0.1.2 pick
  • 0.1.2 pickAll

both pick and pickAll support both dict and object type.

class Obj:
  def __init__(self, v1, v2):
    self.v1 = v1
    self.v2 = v2
obj = Obj(1, 2)
R.pick(['v1'], obj) # {'v1': 1}
R.pickAll(['v1', 'v3'], obj) # {'v1': 1, 'v3': None}
  • pickBy
  • 0.1.2 pipe
  • pipeWith
  • 0.1.2 pluck
# works for both dict and object
class Obj:
  def __init__(self, v1, v2):
    self.v1 = v1
    self.v2 = v2
obj1 = Obj(1, 2)
obj2 = Obj(3, 4)
R.pluck('v1', [obj1, obj2]) # [1, 3]
  • 0.1.2 prepend
  • 0.1.2 product
  • 0.1.2 project
# works for both dict and object
class Obj:
  def __init__(self, v1, v2):
    self.v1 = v1
    self.v2 = v2
obj1 = Obj(1, 2)
obj2 = Obj(3, 4)
R.project(['v1'], [obj1, obj2]) # [{'v1': 1}, {'v1': 3}]
  • promap
  • 0.1.2 prop
  • 0.1.2 propEq
# works for both dict and object
class Obj:
  def __init__(self, v1, v2):
    self.v1 = v1
    self.v2 = v2
obj1 = Obj(1, 2)
R.propEq(1, 'v1', obj1) # True
R.propEq(2, 'v2', obj1) # True
R.propEq(1, 'v2', obj1) # False

R.propEq(1, 'v1', {'v1': 1}) # True
  • propIs
  • propOr
  • 0.1.2 props
  • propSatisfies
  • 0.1.2 range
  • 0.1.2 reduce
  • 0.1.2 reduceBy
  • 0.1.2 reduced
  • 0.1.2 reduceRight
  • reduceWhile
  • 0.1.2 reject
  • remove
  • 0.1.4 repeat
  • replace
  • 0.1.2 reverse
  • scan
  • sequence
  • set
  • 0.1.2 slice
R.slice(1, 3, ['a', 'b', 'c', 'd']) # ['b', 'c']
R.slice(1, None, ['a', 'b', 'c', 'd']) # ['b', 'c', 'd']
  • 0.1.2 sort
  • 0.1.2 sortBy
  • sortWith
  • 0.1.2 split
  • splitAt
  • splitEvery
  • splitWhen
  • splitWhenever
  • startsWith
  • 0.1.2 subtract
# different from ramda
R.subtract(None, None) # float('nan)
R.subtract(date(1,2,3), date(1,2,3)) # float('nan)
  • 0.1.2 sum
  • symmetricDifference
  • symmetricDifferenceWith
  • 0.1.2 T
  • 0.1.2 tail
  • 0.1.2 take
  • takeLast
  • takeLastWhile
  • 0.1.2 takeWhile
  • 0.1.2 tap
  • test
  • thunkify
  • 0.1.4 times
  • toLower
  • toPairs
  • toPairsIn
  • 0.1.2 toString

Partially supported

  1. String type, supported
  2. for others, just use str(x) instead
  • toUpper
  • transduce
  • transpose
  • traverse
  • trim
  • tryCatch
  • type
  • unapply
  • 0.2.0 unary
  • uncurryN
  • unfold
  • 0.1.2 union
  • 0.1.2 unionWith
  • 0.1.2 uniq
  • 0.1.2 uniqBy
  • 0.1.2 uniqWith
  • unless
  • unnest
  • until
  • unwind
  • update
  • 0.1.2 useWith
  • 0.1.2 values
# works for both dict and object
class Obj:
  def __init__(self, v1, v2):
    self.v1 = v1
    self.v2 = v2
obj = Obj(1, 2)
R.values(obj) # [1, 2]
R.values({'a': 1, 'b': 2}) # [1, 2]
  • 0.2.0 valuesIn

Use R.keysIn to get the keys of an object.

  • view
  • when
  • 0.1.4 where

spec(first param) is prefer to be a dict.

method where supports both dict and object as second param.

class Obj:
  def __init__(self, x, y):
    self.x = x
    self.y = y

spec = {'x': R.equals(1)}
R.where(spec, {'x': 1, 'y': 2}) # True
R.where(spec, Obj(1, 2)) # True
  • whereAny
  • whereEq
  • without
  • xor
  • 0.1.2 xprod
  • 0.1.2 zip
  • zipObj
  • 0.1.2 zipWith

Metadata

Release files for python-ramda 0.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for python-ramda 0.2.0
File Size Uploaded
python_ramda-0.2.0.tar.gz 60.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for python-ramda 0.2.0
File Interpreter ABI Platform
python_ramda-0.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 192.4 kB

Release files / python_ramda-0.2.0.tar.gz

Download URL python_ramda-0.2.0.tar.gz
Size 60.2 kB
Tags Source
SHA-256 checksum
How to use checksums
82b9a4ea7e743f02df30832e3ae8b4eb3e14ccde2d28850a1689d4393240ff0e
BLAKE2b-256 checksum
How to use checksums
ae0a2f68c2727bd335084e2bf12fee35a2c878f85b20fac8ab5fd26855caaa76
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.1 CPython/3.10.4

Release files / python_ramda-0.2.0-py3-none-any.whl

Download URL python_ramda-0.2.0-py3-none-any.whl
Size 132.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
3c33f520bf46b2365fda4fccb43754cbc0e6815b06644ee19eb0cc6ea53592c6
BLAKE2b-256 checksum
How to use checksums
b1fb6bbc54293af809592a021c7a6d5b79f19ab32a9680fc198c4323daf09282
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.1 CPython/3.10.4

Release history Release notifications | RSS feed

0.8.0

2 release files

0.7.0

2 release files

0.6.0

2 release files

0.4.1

2 release files

0.4.0

2 release files

0.3.0

2 release files

0.2.2

2 release files

This release

0.2.0 This release

2 release files

0.1.4

2 release files

0.1.2

2 release files

0.1.0.1

1 release file

0.1.0.0

1 release file

0.0.11

2 release files

0.0.10

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page