C API: array of floats/ints from python to C and back

Gabriel Genellina gagsl-py2 at yahoo.com.ar
Sun Dec 28 04:38:44 CET 2008

En Sun, 28 Dec 2008 00:40:52 -0200, Daniel Fetchinson  
<fetchinson at googlemail.com> escribió:

>> You MUST check EVERY function call for errors!
> Yes, I know :)

Believe me, if you don't, there is a risk of crashing the program. And  
they're a lot harder to find and fix.

>> And check the argument's type (how do you know it is a list?). Once you
>> are sure the first parameter *is* a list, you may use the "macro"  
>> version
>> of several functions, like PyList_GET_SIZE and PyList_GET_ITEM.
> The macro versions are preferable because they are faster?

Yes, because they don't do any additional checking. PyList_GET_ITEM just  
retrieves the item; PyList_GetItem checks whether it is called on a list  
object, then checks if index is out of bounds, and only then goes to  
retrieve the item.

>> You should check that both lists have the same length too.
>> And you should check that elements are integers, or convertible to
>> integers (in case of error, PyInt_AsLong returns -1 and PyErr_Occurred()
>> is true)
>> To fill the resulting tuple, use PyTuple_SET_ITEM instead. BTW, why  
>> return
>> a tuple and not a list?
> No particular reason, other than the fact that I won't need to modify
> these lists/tuples from python so whenever something will not change,
> I use a tuple because it's immutable. Or this is not a very good
> practice? There is no difference between lists and tuples in terms of
> speed I suppose (getitem, setitem, etc).

Usually lists represent an ordered collection of similar items, where  
position is not relevant (the third item is treated more or less the same  
as the tenth); by example, a list of attendants to certain event. It makes  
sense to process the whole list doing the same thing to each element, and  
it makes sense to ask "is this item in the list?."

Tuples represent an ordered collection of dissimilar items, where position  
is relevant (because it identifies each item); by example, a row from a  
database table (name, address, age, phone number), or a point (x,y,z) in  
space. It isn't common to process the whole tuple doing the same thing for  
each element, and usually it doesn't make sense to look for certain item  
in the tuple. But it does make sense to refer to individual items like  
t[2], or t.age (namedtuple, 2.6 and up)

 From this point of view, lists and tuples are conceptually different -  
tuples aren't "frozen" lists. But this is just common usage, or maybe  
historical intent; of course you are free to use whatever structure you  
feel adequate.

Once the list/tuple is created and filled, there is no speed difference  
accessing the individual items. Creating an empty list that grows one  
element at a time is slow for large lists (the memory block has to be  
re-allocated and copied over evry time it gets full) but this doesn't  
happen if you provide the final size when creating the list.

Gabriel Genellina

More information about the Python-list mailing list