On Thu, 2006-12-28 at 19:49 +0100, Stef Mientki wrote: > [...] > When I replace the assignment to "filter_prev", by a loop, > the function works as expected. > <Python> > #filter_prev = Extended [ len(Signal_IN) : ] > for i in range( len(filter_prev )): > filter_prev[i] = Extended [ len(Signal_IN) + i ] > </Python>
Let's examine the fundamental difference between the statements filter_prev = Extended [ len(Signal_IN) : ] and filter_prev[i] = Extended [ len(Signal_IN) + i ] . The first statement is an assignment to the local name filter_prev. Prior to that assignment, filter_prev was a reference to whatever object was passed into your function in the fourth argument slot. The assignment makes filter_prev become a reference to the list slice Extended[len(Signal_IN):]. In no way does this affect the object that filter_prev referred to previously. The second statement looks a lot like an assignment, but it is not an assignment. It is a method call. It is equivalent to the method call filter_prev.__setitem__(i, Extended[len(Signal_IN)+i]), which is asking the object that filter_prev refers to to change its i-th item. This does affect the object that filter_prev refers to, which is of course the same object that, in the global namespace, is known as BP_filter_prev. The second approach has the desired side-effect of modifying the list that was passed into the function. The first approach is unable to have such an effect because assignments modify namespaces, not objects. You're modifying the local namespace of the chunk_Filter function, and that change is not made visible to the outside in any way. If you wish to eliminate the for loop, you can do the following: filter_prev[:] = Extended[len(Signal_IN):] This, again, is not an assignment, even though it looks a lot like one. It is equivalent to a __setslice__ method call, which modifies the object that filter_prev refers to by making it replace its entire contents with the contents of the list slice on the right hand side. If you want to write functions with side-effects, you need to understand the difference between somename = someobject on the one hand and somename[something] = someobject or somename.something = someobject. The first is an assignment. It means "make the name somename refer to the object currently known as someobject". It does not matter if somename currently refers to an object, and if it does refer to an object, that object is not modified or even consulted in any way. The second kind looks superficially like assignments, but they are in fact __setitem__/__setslice__/__setattr__ method calls in disguise. For them to succeed, somename must refer to an object that implements the corresponding method, and those methods will cause the object known as somename to modify itself. After all that, you should now be sufficiently discouraged from attempting to write functions with side effects. :) You can achieve the same result without side-effects by returning more than one return value from your function. Hope this helps, Carsten. -- http://mail.python.org/mailman/listinfo/python-list