Sometimes, I just want to execute a function for a list of entries -- eg.:
for x in wowList:
installWow(x, 'installed by me')
Sometimes I need this stuff for module initialization, so I don't want to have a footprint like x in global namespace. One solution would be to just use map together with lambda:
map(lambda x: installWow(x, 'installed by me'), wowList)
But this of course creates a nice list [None, None, ...] so my question is, if there is a similar function without a return-list -- since I just don't need it.
(off course I can also use _x and thus not leaving visible footprint -- but the map-solution looks so neat ...)
Let me preface this by saying that it seems the original poster was more concerned about namespace clutter than anything else. In that case, you can wrap your working variables in separate function namespace and call it after declaring it, or you can simply remove them from the namespace after you've used them with the "del" builtin command. Or, if you have multiple variables to clean up, def the function with all the temp variables in it, run it, then del it.
Read on if the main concern is optimization:
Three more ways, potentially faster than others described here:
But the real problem here is the fact that a function returns something and you do not want it to return anything.. So to resolve this, you have 2 options. One is to refactor your code so installWow takes in the wowList and iterates it internally. Another is rather mindblowing, but you can load the installWow() function into a compiled ast like so:
You can then do the same for the outer function, and traverse the ast to find the for loop. Then in the body of the for loop, insert the instalWow() function ast's function definition body, matching up the variable names. You can then simply call exec on the ast itself, and provide a namespace dictionary with the right variables filled in. To make sure your tree modifications are correct, you can check what the final source code would look like by running astunparse.
And if that isn't enough you can go to cython and write a .pyx file which will generate and compile a .c file into a library with python bindings. Then, at least the lost cycles won't be spent converting to and from python objects and type-checking everything repeatedly.
You can use the built-in
any
function to apply a function without return statement to any item returned by a generator without creating a list. This can be achieved like this:I found this the most concise idom for what you want to achieve.
Internally, the
installWow
function does returnNone
which evaluates toFalse
in logical operations.any
basically applies anor
reduction operation to all items returned by the generator, which are allNone
of course, so it has to iterate over all items returned by the generator. In the end it does returnFalse
, but that doesn't need to bother you. The good thing is: no list is created as a side-effect.Note that this only works as long as your function returns something that evaluates to
False
, e.g.,None
or 0. If it does return something that evaluates toTrue
at some point, e.g.,1
, it will not be applied to any of the remaining elements in your iterator. To be safe, use this idiom mainly for functions without return statement.You could use a filter and a function that doesn't return a True value. You'd get an empty return list since filter only adds the values which evaluates to true, which I suppose would save you some memory. Something like this:
Running it produces this output:
Just make installWow return None or make the last statement be pass like so:
and use this:
x won't be set in the global name space and the list returned is [] a singleton
if it is ok to distruct wowList
if you do want to maintain wowList
and if order matters
Though as the solution of the puzzle I like the first :)
If you're worried about the need to control the return value (which you need to do to use filter) and prefer a simpler solution than the reduce example above, then consider using reduce directly. Your function will need to take an additional first parameter, but you can ignore it, or use a lambda to discard it: