Commit 5e08f882 authored by scoder's avatar scoder

Merge pull request #273 from andreasvc/master

tutorial for Python arrays
parents cd76e995 a01c8398
============================
Working with Python arrays
============================
Python has a builtin array module supporting dynamic 1-dimensional arrays of
primitive types. It is possible to access the underlying C array of a Python
array from within Cython. At the same time they are ordinary Python objects
which can be stored in lists and serialized between processes when using
:obj:`multiprocessing`.
Compared to the manual approach with :c:func:`malloc` and :c:func:`free`, this
gives the safe and automatic memory management of Python, and compared to a
Numpy array there is no need to install a dependency, as the :obj:`array`
module is built into both Python and Cython.
Safe usage with memory views
----------------------------
.. code-block:: python
from cpython cimport array
from array import array
cdef array.array a = array('i', [1, 2, 3])
cdef int[:] ca = a
print ca[0]
A Python array is constructed with a type signature and sequence of
initial values. For the possible type signatures, refer to the Python
documentation for the `array module <http://docs.python.org/library/array.html>`_.
Notice that when a Python array is assigned to a variable typed as
memory view, there will be a slight overhead to construct the memory
view. However, from that point on the variable can be passed to other
functions without overhead, so long as it is typed:
.. code-block:: python
from cpython cimport array
from array import array
cdef array.array a = array('i', [1, 2, 3])
cdef int[:] ca = a
cdef int overhead(object a):
cdef int[:] ca = a
return ca[0]
cdef int no_overhead(int[:] ca):
return ca[0]
print overhead(a) # new memory view will be constructed, overhead
print no_overhead(ca) # ca is already a memory view, so no overhead
Zero-overhead, unsafe access to raw C pointer
---------------------------------------------
To avoid any overhead and to be able to pass a C pointer to other
functions, it is possible to access the underlying contiguous array as a
pointer. There is no type or bounds checking, so be careful to use the
right type and signedness.
.. code-block:: python
from cpython cimport array
from libc.string cimport memset
from array import array
cdef array.array a = array('i', [1, 2, 3])
# access underlying pointer:
print a.data.as_ints[0]
memset(a.data.as_voidptr, 0, len(a) * sizeof(int))
Cloning, extending arrays
-------------------------
To avoid having to use the array constructor from the Python module,
it is possible to create a new array with the same type as a template,
and preallocate a given number of elements. The array is initialized to
zero when requested.
.. code-block:: python
from cpython cimport array
from array import array
cdef array.array int_array_template = array('i', [])
cdef array.array newarray
# create an array with 3 elements with same type as template
newarray = array.clone(int_array_template, 3, False)
An array can also be extended and resized; this avoids repeated memory
reallocation which would occur if elements would be appended or removed
one by one.
.. code-block:: python
from cpython cimport array
from array import array
cdef array.array a = array('i', [1, 2, 3])
cdef array.array b = array('i', [4, 5, 6])
# extend a with b, resize as needed
array.extend(a, b)
# resize a, leaving just original three elements
array.resize(a, len(a) - len(b))
......@@ -15,6 +15,7 @@ Tutorials
memory_allocation
pure
numpy
array
readings
related_work
appendix
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment