Welcome!

Introduction

_images/logo.png

Python Project vectorize

GitHubWorkflow Read the Docs GitHub GitHub release PyPI Version PyPI - Python Version PyPI Downloads

Introduction

To import the project simply type

>>> from vectorizeit import vectorize

after installation and use vectorize as a decorator to iterate over arguments of list type.

>>> @vectorize()
... def foo(a, b):
...     return a, b

>>> foo((1, 2), ['a', 'b'])
(((1, 'a'), (1, 'b')), ((2, 'a'), (2, 'b')))

This works also with specifying arguments to be vectorized.

>>> @vectorize(keys=['b'])
... def foo(a, b):
...     return a, b

>>> foo((1, 2), ['a', 'b'])
((1, 2), 'a'), ((1, 2), 'b'))

Setting the zipped decorator argument will iter in parallel over the multiple vector inputs as have been zipped.

>>> @vectorize(keys=['b', 'c'], zipped=True)
... def foo(a, b):
...     return a, b

>>> foo((1, 2), ['a', 'b'])
((1, 'a'), (2, 'b'))

For more see the detailed documentation.

Install

The latest stable version can always be installed or updated via pip:

$ pip install vectorizeit

License

Code and documentation are available according to the license (see LICENSE file in repository).

Tutorial

>>> from vectorizeit import vectorize

>>> @vectorize(keys=['a', 'b'])
... def foo(a, b):
...     return a, b

>>> foo((1, 2), ('a', 'b'))
(((1, 'a'), (1, 'b')), ((2, 'a'), (2, 'b')))

But there is more to explore. For instance, the return type is the same as the vector argument type.

>>> foo([1, 2], ['a', 'b'])
[[(1, 'a'), (1, 'b')], [(2, 'a'), (2, 'b')]]

To flatten such tensor use

>>> from itertools import chain
>>> list(chain.from_iterable(foo([1, 2], ['a', 'b'])))
[(1, 'a'), (1, 'b'), (2, 'a'), (2, 'b')]

Or even

>>> @vectorize(keys=['b'])
... def foo(a, b, c=None, *args, **kwargs):
...     return a, b, c, args, kwargs
>>> r = foo(1, ['b1', 'b2'], d=[10, 11])
>>> type(r)
<class 'list'>
>>> r
[(1, 'b1', None, (), {'d': [10, 11]}), (1, 'b2', None, (), {'d': [10, 11]})]

This works also with multiple arguments and multiple vector inputs.

>>> @vectorize(keys=['b', 'c'])
... def foo(a, b, c=None, *args, **kwargs):
...     return a, b, c, args, kwargs
>>> foo(1, ['b1', 'b2'], c=(1, 2), d=[10, 11])
[((1, 'b1', 1, (), {'d': [10, 11]}), (1, 'b1', 2, (), {'d': [10, 11]})), ((1, 'b2', 1, (), {'d': [10, 11]}), (1, 'b2', 2, (), {'d': [10, 11]}))]

Setting the zipped decorator argument will iter in parallel over the mutiple vector inputs as have been zipped.

>>> @vectorize(keys=['b', 'c'], zipped=True)
... def foo(a, b, c=None, *args, **kwargs):
...     return a, b, c, args, kwargs
>>> foo(1, ['b1', 'b2'], c=(1, 2), d=[10, 11])
((1, 'b1', 1, (), {'d': [10, 11]}), (1, 'b2', 2, (), {'d': [10, 11]}))

To fix the return value type set returns.

>>> @vectorize(keys=['b', 'c'], returns=list)
... def foo(a, b, c=None, *args, **kwargs):
...     return a, b, c, args, kwargs
>>> foo(1, ['b1', 'b2'], d=[10, 11])
[(1, 'b1', None, (), {'d': [10, 11]}), (1, 'b2', None, (), {'d': [10, 11]})]

In order to avoid unexpected vectorization one can fix specific types to be vectorized by setting types.

>>> @vectorize(keys=['b', 'c'], types=(list,))
... def foo(a, b, c=None, *args, **kwargs):
...     return a, b, c, args, kwargs
>>> foo(1, ['b1', 'b2'], d=[10, 11])
[(1, 'b1', None, (), {'d': [10, 11]}), (1, 'b2', None, (), {'d': [10, 11]})]
>>> foo(1, ('b1', 'b2'), d=[10, 11])
(1, ('b1', 'b2'), None, (), {'d': [10, 11]})

vectorize works for methods, too.

>>> class vector(list):
...
...    @vectorize(keys=['item'])
...    def __getitem__(self, item):
...        return super().__getitem__(item)
>>> v = vector(range(3))
>>> v
[0, 1, 2]
>>> v[(2, 1)]
(2, 1)

And to be more careful use a custom class to control vectorization.

>>> @vectorize(keys=['b', 'c'], types=(vector,))
... def foo(a, b, c=None, *args, **kwargs):
...     return a, b, c, args, kwargs
>>> foo(1, ['b1', 'b2'], d=[10, 11])
(1, ['b1', 'b2'], None, (), {'d': [10, 11]})
>>> foo(1, vector(('b1', 'b2')), d=[10, 11])
[(1, 'b1', None, (), {'d': [10, 11]}), (1, 'b2', None, (), {'d': [10, 11]})]

API Documentation

vectorizeit

vectorizeit package

Submodules
vectorizeit.vectorizeit.vectorize(keys=(), varargs=True, varkw=True, types=None, returns=None, zipped=False)[source]

simply vectorize Python functions and methods by iteration.

Parameters
  • keys – set keys to identify arguments to iterate by default all arguments are vectorized if keys is None no argument is vectorized

  • varargs – allowd variable argumnents to be vectorized (default: True)

  • varkw – allowd variable keyword argumnents to be vectorized (default: True)

  • types – only arguments of types as specified in types will be vectorized. If not spefivied this defaults to list, tuple, set and dict.

  • returns – the type of return value is set by returns by default the return value has the same type as the vectorized argument. If set to ‘none’ no value ist returned. Only if zipped is True the default return type is tuple.

  • zipped – if multiple arguments are vectors zipped sets the way to iterate, either - by default - tensor-like, i.e. one argumnet after the other which resuts in nested vectors, or as zipped is True by iterating of all vector argunments in parallel and at once.

Simply use the decorator to vectorize a function.

>>> from vectorizeit import vectorize
>>> @vectorize()
... def foo(a, b, c=None, *args, **kwargs):
...     return a, b, c, args, kwargs
>>> r = foo(1, ['b1', 'b2'], d=[10, 11])
>>> type(r)
<class 'list'>
>>> r
[[(1, 'b1', None, (), {'d': 10}), (1, 'b1', None, (), {'d': 11})], [(1, 'b2', None, (), {'d': 10}), (1, 'b2', None, (), {'d': 11})]]

This works also with specifying arguments to be vectorized.

>>> @vectorize(keys=['b'])
... def foo(a, b, c=None, *args, **kwargs):
...     return a, b, c, args, kwargs
>>> r = foo(1, ['b1', 'b2'], d=[10, 11])
>>> type(r)
<class 'list'>
>>> r
[(1, 'b1', None, (), {'d': [10, 11]}), (1, 'b2', None, (), {'d': [10, 11]})]

This works also with multiple arguments and multiple vector inputs.

>>> @vectorize(keys=['b', 'c'])
... def foo(a, b, c=None, *args, **kwargs):
...     return a, b, c, args, kwargs
>>> foo(1, ['b1', 'b2'], c=(1, 2), d=[10, 11])
[((1, 'b1', 1, (), {'d': [10, 11]}), (1, 'b1', 2, (), {'d': [10, 11]})), ((1, 'b2', 1, (), {'d': [10, 11]}), (1, 'b2', 2, (), {'d': [10, 11]}))]

Setting the zipped decorator argument will iter in parallel over the multiple vector inputs as have been zipped.

>>> @vectorize(keys=['b', 'c'], zipped=True)
... def foo(a, b, c=None, *args, **kwargs):
...     return a, b, c, args, kwargs
>>> foo(1, ['b1', 'b2'], c=(1, 2), d=[10, 11])
((1, 'b1', 1, (), {'d': [10, 11]}), (1, 'b2', 2, (), {'d': [10, 11]}))

To fix the return value type set returns.

>>> @vectorize(keys=['b', 'c'], returns=list)
... def foo(a, b, c=None, *args, **kwargs):
...     return a, b, c, args, kwargs
>>> foo(1, ['b1', 'b2'], d=[10, 11])
[(1, 'b1', None, (), {'d': [10, 11]}), (1, 'b2', None, (), {'d': [10, 11]})]

In order to avoid unexcpected vectorization one can fix specific types to be vectorized by setting types.

>>> @vectorize(keys=['b', 'c'], types=(list,))
... def foo(a, b, c=None, *args, **kwargs):
...     return a, b, c, args, kwargs
>>> foo(1, ['b1', 'b2'], d=[10, 11])
[(1, 'b1', None, (), {'d': [10, 11]}), (1, 'b2', None, (), {'d': [10, 11]})]
>>> foo(1, ('b1', 'b2'), d=[10, 11])
(1, ('b1', 'b2'), None, (), {'d': [10, 11]})

vectorize works for methods, too.

>>> class vector(list):
...
...    @vectorize(keys=['item'])
...    def __getitem__(self, item):
...        return super().__getitem__(item)
>>> v = vector(range(3))
>>> v
[0, 1, 2]
>>> v[(2, 1)]
(2, 1)

And to be more careful use a custom class to control vectorization.

>>> @vectorize(keys=['b', 'c'], types=(vector,))
... def foo(a, b, c=None, *args, **kwargs):
...     return a, b, c, args, kwargs
>>> foo(1, ['b1', 'b2'], d=[10, 11])
(1, ['b1', 'b2'], None, (), {'d': [10, 11]})
>>> foo(1, vector(('b1', 'b2')), d=[10, 11])
[(1, 'b1', None, (), {'d': [10, 11]}), (1, 'b2', None, (), {'d': [10, 11]})]
Module contents

simply vectorize Python functions and methods by iteration.

Releases

These changes are listed in decreasing version number order.

Release 0.1

Release date was Monday, 15 May 2023

  • new default keys argument

  • explicit handling of variable-length arguments adn keyword arguments

Release 0.1

Release date was Tuesday, 09 May 2023

  • initial release

Indices and tables