Skip to main content

The Pattern Matching for Python you always dreamed of

Project description

Pampy in Star Wars

Pampy: Pattern Matching for Python3

License MIT Travis-CI Status Coverage Status PyPI version

Pampy is pretty small, pretty fast, and often makes your code more readable, and easier to reason about.

You can write many patterns

Patterns are evaluated in the order they appear.

You can write Fibonacci

The operator _ means "any other case I didn't think of".

from pampy import match, _

def fibonacci(n):
    return match(n,
        1, 1,
        2, 1,
        _, lambda x: fibonacci(x-1) + fibonacci(x-2)
    )

You can write a Lisp calculator in 5 lines

from pampy import match, REST, _

def lisp(exp):
    return match(exp,
        int,                lambda x: x,
        callable,           lambda x: x,
        (callable, REST),   lambda f, rest: f(*map(lisp, rest)),
        tuple,              lambda t: list(map(lisp, t)),
    )

plus = lambda a, b: a + b
minus = lambda a, b: a - b
from functools import reduce

lisp((plus, 1, 2))                 # => 3
lisp((plus, 1, (minus, 4, 2)))     # => 3
lisp((reduce, plus, (1, 2, 3))     # => 6

You can match so many things!

match(x,
    3,              "this matches the number 3",

    int,            "matches any integer",

    (str, int),     lambda a, b: "a tuple (a, b) you can use in a function",

    [1, 2, _],      "any list of 3 elements that begins with [1, 2]",

    {'x': _},       "any dict with a key 'x' and any value associated",

    _,              "anthing else"
)

You can match [HEAD, TAIL]

from pampy import match, HEAD, TAIL, _

x = [1, 2, 3]

match(x, [1, TAIL],     lambda t: t)            # => [2, 3]

match(x, [HEAD, TAIL],  lambda h, t: (h, t))    # => (1, [2, 3])

You can nest lists and tuples

from pampy import match, _

x = [1, [2, 3], 4]

match(x, [1, [_, 3], _], lambda a, b: [1, [a, 3], b])       # => [1, [2, 3], 4]

You can nest dicts. And you can use _ as key!

pet = { 'type': 'dog', 'details': { 'age': 3 } }

match(pet, { 'details': { 'age': _ } }, lambda age: age)        # => 3

match(pet, { _ : { 'age': _ } },        lambda a, b: (a, b))    # => ('details', 3)

It feels like putting multiple _ inside dicts shouldn't work. Isn't ordering in dicts not guaranteed ? But it does because in Python 3.7, dict is an OrderedDict by default

All the things you can match

As Pattern you can use any Python type, any class, or any Python value.

The operator _ and types like int or str, extract variables that are passed to functions.

Types and Classes are matched via instanceof(value, pattern).

Iterable Patterns match recursively through all their elements. The same goes for dictionaries.

Pattern Example What it means Matched Example Arguments Passed to function NOT Matched Example
"hello" only the string "hello" matches "hello" "hello" any other value
int Any integer 42 42 any other value
float Any float number 2.35 2.35 any other value
str Any string "hello" "hello" any other value
tuple Any tuple (1, 2) (1, 2) any other value
list Any list [1, 2] [1, 2] any other value
MyClass Any instance of MyClass MyClass() that instance any other object instance
_ Any object (even None)
ANY The same as _
(int, int) A tuple made of any two integers (1, 2)
[1, 2, _] A list that starts with 1, 2 and ends with any value [1, 2, 3] 3 [1, 2, 3, 4]
[1, 2, TAIL] A list that start with 1, 2 and ends with any sequence [1, 2, 3, 4] [3, 4] [1, 7, 7, 7]
{'type':'dog', age: _ } Any dict with type: "dog" and with an age {"type":"dog", "age": 3} 3 {"type":"cat", "age":2}
{'type':'dog', age: int } Any dict with type: "dog" and with an int age {"type":"dog", "age": 3} 3 {"type":"dog", "age":2.3}

Install

Currently it works only in Python 3 Because dict matching can work only in the latest Pythons.

Support for Python2 is coming.

To install it:

$ pip install pampy

or $ pip3 install pampy

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

pampy-0.1.3.tar.gz (8.5 kB view details)

Uploaded Source

Built Distribution

pampy-0.1.3-py3-none-any.whl (10.0 kB view details)

Uploaded Python 3

File details

Details for the file pampy-0.1.3.tar.gz.

File metadata

  • Download URL: pampy-0.1.3.tar.gz
  • Upload date:
  • Size: 8.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/1.12.1 pkginfo/1.4.2 requests/2.20.1 setuptools/40.5.0 requests-toolbelt/0.8.0 tqdm/4.28.1 CPython/3.6.5

File hashes

Hashes for pampy-0.1.3.tar.gz
Algorithm Hash digest
SHA256 0d6e3222b7f7920b6237645d9255ab739059ccc2db24174bbe29eb00f6afc37d
MD5 8b0123b6751f75cbe976c09a6afcdcf6
BLAKE2b-256 c14b5137d877316c9681140c764b2d74e701cc6d97f66ee7dc6a730304fdc3be

See more details on using hashes here.

File details

Details for the file pampy-0.1.3-py3-none-any.whl.

File metadata

  • Download URL: pampy-0.1.3-py3-none-any.whl
  • Upload date:
  • Size: 10.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/1.12.1 pkginfo/1.4.2 requests/2.20.1 setuptools/40.5.0 requests-toolbelt/0.8.0 tqdm/4.28.1 CPython/3.6.5

File hashes

Hashes for pampy-0.1.3-py3-none-any.whl
Algorithm Hash digest
SHA256 d78cdb837c6e61d8e13d4c87797f056e566198ee52128458d066a6ddbac9fb12
MD5 c25df4bf8a2c75101a3938d533faefd7
BLAKE2b-256 709e3a8c3701d9be9c10fd4118327ac05a3d733d3779fd13b875dd189595a576

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page