Python function long parameter list - python

I'm looking for the best way to give a list of arguments to my function :
def myFunc(*args):
retVal=[]
for arg in args:
retVal.append(arg+1)
return "test",retVal
The problem is that it becomes very annoying when you have a long list of parameters to pass to your function because you have to write two times your whole list of parameters and When you have 10 parameters or more with complete names, it becomes really (really) heavy.
test,alpha,beta,gamma,delta,epsilon,zeta,eta,theta,iota=myFunc(alpha,beta,gamma,delta,epsilon,zeta,eta,theta,iota)
So I thought about something like this :
w=alpha,beta,gamma,delta,epsilon,zeta,eta,theta,iota
test,w=myFunc(w)
But then I sill have to do :
alpha,beta,gamma,delta,epsilon,zeta,eta,theta,iota=w
Is there any shorter way to give and get back a list of parameter from a function.
Or give a pointer to the function for it to modify directly the parameters ?
This is what I'm looking for :
w=alpha,beta,gamma,delta,epsilon,zeta,eta,theta,iota
test,w=myFunc(w)
# And directly get my parameters modified to be able to print them :
print alpha,[...],iota

Two options:
Try reducing the number of arguments by splitting the logic into multiple functions.
If 1.) is not possible, you can use a dictionary a single argument - encapsulating all your arguments. This would be a flexible (signature of function stays the same, even if you take away or add parameters) and mostly readable solution (meaningful keys in the dictionary).

Simply make the function return a dict. Then you can call it using myFunc(**yourdict) to use the dict items as arguments and if you return yourdict you get back the same dict (with probably modified values) - or you just modify the original dict and don't return one at all.

Related

A function that creates a function with parameters

I am writing a function that will take a sequence of strings as a parameter, and then return a function (probably a lambda) where those strings are the names of the parameters. I can make it return a function, but I can't quite figure out how to set the parameters of the returned function.
i.e. if I gave called make_a_new_function(('a','b','c','d')) the returned function would have four parameters: a, b, c and d.
I know that the function.__code__.co_varnames is stored as a tuple of strings, but it's a read-only value so I can't edit it.
Is what I'm wanting possible? Or am I going mad over impossible dreams?
EDIT: Turns out there was a good alternative by constructing a string of python syntax, then using eval() to call the expression.
With the aid of some people in the comments, I determined that the best way to do get what I was aiming for would be to construct the expression as a string. This could then be evaluated using the eval() function, as long as the string was syntactically correct.
def logic_AND_expression(*parameters)
return ' and '.join(*parameters)
eval(logic_AND_expression('A','B','C','D'),{'A'=True,'B'=False,'C'=True,'D'=True})
False

Python: Can you dynamically get the amount of variables a function is going to return into?

Part of a utility system my AcecoolLib package I'm writing by porting all / most of my logic to Python, and other various languages, on contains a simple, but greatly useful helper... a function named ENUM.
It has many useful features, such as automatically creating maps of the enums, extended or reverse maps if you have the map assigned to more than just values, and a lot more.
It can create maps for generating function names dynamically, it can create simple maps between enumeration and text or string identifiers for language, and much more.
The function declaration is simple, too:
def ENUM( _count = None, *_maps ):
It has an extra helper... Here: https://www.dropbox.com/s/6gzi44i7dh58v61/dynamic_properties_accessorfuncs_and_more.py?dl=0
The other one isn't used. ENUM_MAP is, but the other isn't.
Anyway, before I start going into etc.. etc.. the question is:
How can I count the return variables outside of the function... ie:
ENUM_EXAMPLE_A, ENUM_EXAMPLE_B, ENUM_EXAMPLE_C, ENUM_LIST_EXAMPLE, MAP_ENUM_EXAMPLE = ENUM( None, [ '#example_a', '#example_b', '#example_c' ] )
Where List is a simple list of 0 = 0, 1 = 1, 2 = 2, or something. , then the map links so [ 0 = '#example_a', 1 = '#example_b', etc.. ], then [ '#example_a' = 0, etc.. ] for reverse... or something along those lines.
There are other advanced use cases, not sure if I have those features in the file above, but regardless... I'm trying to simply count the return vars... and get the names.
I know it is likely possible, to read the line from which the call is executed... read the file, get the line, break it apart and do all of that... but I'm hoping something exists to do that without having to code it from scratch in the default Python system...
in short: I'd like to get rid of the first argument of ENUM( _count, *_maps ) so that only the optional *_maps is used. So if I call: ENUM_A, ENUM_B, ENUM_C, LIST_ENUMS = ENUM( ); it'll detect 4 output returns, and get the name of them so I can see if the last contains certain text different from the style of the first... ie, if they want the list, etc.... If they add a map, then optional list, etc.. and I can just count back n _maps to find the list arg, or not...
I know it probably isn't necessary, but I want it to be easy and dynamic so if I add a new enum to a giant list, I don't have to add the number ( although for those I use the maps which means I have to add an entry anyway )...
Either way - I know in Lua, this is stupid easy to do with built-in functions.. I'm hoping Python has built in functions to easily grab the data too.
Thanks!
Here is the one proposed answer, similar to what I could do in my Lua framework... The difference, though, is my framework has to load all of the files into memory ( for dynamic reloading, and dynamic changes, going to the appropriate location - and to network the data by combining everything so the file i/o cost is 'averted' - and Lua handles tables incredibly well ).
The simple answer, is that it is possible.. I'm not sure about in default Python without file i/o, however this method would easily work. This answer will be in pseudo context - but the functionality does exist.
Logic:
1) Using traces, you can determine which file / path and which line, called the ENUM function.
2) Read the calling file as text -- if you can read directly to a line without having to process the entire file - then that would be quicker. There may be some libraries out there that do this. In default Python, I haven't done a huge amount of file i/o other than the basics so I'm not up to speed on all of the most useful things as I typically use SQL for storage purposes, etc...
3) With the line in question, split the line text on '=', ie: before the function call to have the arguments, and the function itself.. call it _result
4)a IF you have no results then someone called the function without returning anything - odd..
4) split _result[ 0 ] on ',' to get each individual argument, and trim whitespace left / right --
5) Combine the clean arguments into a list..
6) Process the args -- ie: determine the method the developer uses to name their enum values, and see if that style changes from the last argument ( if no map ). If map, then go back n or n*2 elements for the list, then onward from there for the map vars. With maps, map returns are given - the only thing I need to do dynamically is the number and determine if the user has a list arg, or not..
Note: There is a very useful and simple mechanism in Python to do a lot of these functions in-line with a single line of code.
All of this is possible, and easy to create in Python. The thing I dislike about this solution is the fact that it requires file i/o -- If your program is executed from another program, and doesn't remain in memory, this means these tasks are always repeated making it less friendly, and more costly...
If the program opens, and remains open, then the cost is more up-front instead of on-going making it not as bad.
Because I use ENUMs in everything, including quick executable scripts which run then close - I don't want to use file i/o..
But, a solution does exist. I'm looking for an alternate.
Simple answer is you can't.
In Python when you do (a, b, c) = func() it's called tuple unpacking. Essentially it's expecting func() to return a tuple of exactly 3 elements (in this example). However, you can also do a = func() and then a will contain a 3-element tuple or whatever func decided to return. Regardless of how func is called, there's nothing within the method that knows how the return value is going to be processed after it's returned.
I wanted to provide a more pythonic way of doing what you're intending, but I'm not really sure I understand the purpose of ENUM(). It seems like you're trying to create constants, but Python doesn't really have true constants.
EDIT:
Methods are only aware of what's passed in as arguments. If you want some sort of ENUM to value mapping then the best equivalent is a dict. You could then have a method that took ENUM('A', 'B', 'C') and returned {'A':0, 'B':1, 'C':2} and then you'd use dict look-ups to get the values.
enum = ENUM('A', 'B', 'C')
print(enum['A']) # prints 0

What happens when a python function that takes arguments called without defining parameters?

L=[5,10,4,2,8,7]
def compare(a,b):
return cmp(b,a)
L.sort(compare)
print (L[-2])
L.sort()
print (L[2])
When this code is run, why a exception is not thrown since the function compare called within sort function has not been given exactly two arguments?
when the code is run it gives the output as,
4
5
You are not calling directly the function
You are passing to the sort function a 'pointer' or a 'reference' to the function that will be used as a comparator
if you need more debugging info add a line that print what is being compared as follow
L=[5,10,4,2,8,7]
def compare(a,b):
print 'comparing ',a,b
return cmp(b,a)
L.sort(compare)
and you will also notice that the number of calls depends on L dis-order
there are several ways to solve the problem of order an array
some of that are merge-sort , binary-sort and still others
this is the link to the source code of python list object
You are not calling compare in L.sort(compare). You are just passing a reference to the function that will be called internally by sort.
You don't need any other arguments for that. Remember that in order to call a function you use (), so if you were actually calling it you would have written L.sort(compare())

Default empty lists vs. *args in Python

I have a function (which I'll call foo) that modifies a list (which I'll call my_list). foo does not always want to modify my_list in the same way; its behavior should influenced by its other arguments (which I'll call other_inputs). Here's some pseudocode:
def foo(my_list, other_inputs):
for input in other_inputs:
my_list.bar(input)
return my_list
I can see two ways to format other_inputs.
I could use *args:
def foo(my_list, *other_inputs):
for input in other_inputs:
my_list.bar(input)
return my_list
Alternately, I could make other_inputs a list, empty by default:
def foo(my_list, other_inputs=[]):
for input in other_inputs:
my_list.bar(input)
return my_list
I've tested it on my machine and both options seem to do the same thing. Which one is preferable?
(Assume that this foo() is called many times, each time with a new other_inputs read in from some external source. Also assume that other_inputs is never appended to or mutated in any other way between external reads, so this isn't a problem.)
Since you are reading other_inputs from another source, you presumably already have a sequence. That argues for the second approach:
def foo(my_list, other_inputs=None):
if other_inputs is not None:
# Assume other_inputs is some type of iterable
for input in other_inputs:
my_list.bar(input)
return my_list
However, you could still use the first approach and call foo with
foo(some_list, *inputs)
It's mostly a matter of preference.
Obviously both of the options are correct, it would be wrong to say one of them is not.
If all other arguments passing to be function are of same type(by same type means they all change input then), then both approaches are equivalent. It is just a matter of preference as suggested by #chepner
But if there is some additional argument (say , expected length of output) which is going to be used differently from other params, then using list explicitly would be a better design.

python how to memoize a method

Say I a method to create a dictionary from the given parameters:
def newDict(a,b,c,d): # in reality this method is a bit more complex, I've just shortened for the sake of simplicity
return { "x": a,
"y": b,
"z": c,
"t": d }
And I have another method that calls newDict method each time it is executed. Therefore, at the end, when I look at my cProfiler I see something like this:
17874 calls (17868 primitive) 0.076 CPU seconds
and of course, my newDict method is called 1785 times. Now, my question is whether I can memorize the newDict method so that I reduce the call times? (Just to make sure, the variables change almost in every call, though I'm not sure if it has an effect on memorizing the function)
Sub Question: I believe that 17k calls are too much, and the code is not efficient. But by looking at the stats can you also please state whether this is a normal result or I have too many calls and the code is slow?
You mean memoize not memorize.
If the values are almost always different, memoizing won't help, it will slow things down.
Without seeing your full code, and knowing what it's supposed to do, how can we know if 17k calls is a lot or the little?
If by memorizing you mean memoizing, use functools.lru_cache.
It's a function decorator
The purpose of memoizing is to save a result of an operation that was expensive to perform so that it can be provided a second, third, etc., time without having to repeat the operation and repeatedly incur the expense.
Memoizing is normally applied to a function that (a) performs an expensive operation, (b) always produces the same result given the same arguments, and (c) has no side effects on the program state.
Memoizing is typically implemented within such a function by 'saving' the result along with the values of the arguments that produced that result. This is a special form of the general concept of a cache. Each time the function is called, the function checks its memo cache to see if it has already determined the result that is appropriate for the current values of the arguments. If the cache contains the result, it can be returned without the need to recompute it.
Your function appears to be intended to create a new dict each time it is called. There does not appear to be a sensible way to memoize this function: you always want a new dict returned to the caller so that its use of the dict it receives does not interfere with some other call to the function.
The only way I can visualize using memoizing would be if (1) the computation of one or more of the values placed into the result are expensive (in which case I would probably define a function that computes the value and memoize that function) or (2) the newDict function is intended to return the same collection of values given a particular set of argument values. In the latter case I would not use a dict but would instead use a non-modifiable object (e.g., a class like a dict but with protections against modifying its contents).
Regarding your subquestion, the questions you need to ask are (1) is the number of times newDict is being called appropriate and (2) can the execution time of each execution of newDict be reduced. These are two separate and independent questions that need to be individually addressed as appropriate.
BTW your function definition has a typo in it -- the return should not have a 'd' between the return keyword and the open brace.

Categories

Resources