15

I have written a python script which calls a function. This function takes 7 list as parameters inside the function, something like this:

def WorkDetails(link, AllcurrValFound_bse, AllyearlyHLFound_bse, 
                AlldaysHLFound_bse, AllvolumeFound_bse, 
                AllprevCloseFound_bse, AllchangePercentFound_bse, 
                AllmarketCapFound_bse):

where all the arguments except link are lists. But this makes my code looks pretty ugly. I pass these lists to this function because the function appends few values in all of these lists. How can I do it in more readable way for other users?

1
  • Does it add the same things to each list or different things? Commented Nov 25, 2012 at 17:11

6 Answers 6

25

test function:

You can use multiple arguments represented by *args and multiple keywords represented by **kwargs and passing to a function:

def test(*args, **kwargs):
    print('arguments are:')
    for i in args:
        print(i)

    print('\nkeywords are:')
    for j in kwargs:
        print(j)

Example:

Then use any type of data as arguments and as many parameters as keywords for the function. The function will automatically detect them and separate them to arguments and keywords:

a1 = "Bob"      #string
a2 = [1,2,3]    #list
a3 = {'a': 222, #dictionary
      'b': 333,
      'c': 444}

test(a1, a2, a3, param1=True, param2=12, param3=None)

Output:

arguments are:
Bob
[1, 2, 3]
{'a': 222, 'c': 444, 'b': 333}

keywords are:
param3
param2
param1
Sign up to request clarification or add additional context in comments.

Comments

5

You can change it to:

def WorkDetails(link, details):

Then invoke it as:

details = [ AllcurrValFound_bse, AllyearlyHLFound_bse, 
            AlldaysHLFound_bse, AllvolumeFound_bse, 
            AllprevCloseFound_bse, AllchangePercentFound_bse, 
            AllmarketCapFound_bse ]
workDetails(link, details)

And you would get the different values out of details by:

AllcurrValFound_bse = details[0]
AllyearlyHLFound_bse = details[1]
...

It would be more robust to turn details into a dictionary, with the variable names as keys, so take your pick between a few more lines of code vs. defensive programming =p

Comments

4

You could use *args if you don't need to use names for your lists:

def WorkDetails(link, *args):
    if args[0] == ... # Same as if AllcurrValFound_bse == ...
        ...

 # Call the function:
 WorkDetails(link, AllcurrValFound_bse, AllyearlyHLFound_bse, AlldaysHLFound_bse, AllvolumeFound_bse, AllprevCloseFound_bse, AllchangePercentFound_bse, AllmarketCapFound_bs)

Or you could use a dictionary

def WorkDetails(link, dict_of_lists):
    if dict_of_lists["AllcurrValFound_bse"] == ...
        ...

# Call the function
myLists = {
    "AllcurrValFound_bse": AllcurrValFound_bse,
    "AllyearlyHLFound_bse": AllyearlyHLFound_bse,
    ...,
    ...
}
WorkDetails(link, myLists)

2 Comments

lipstick on a pig, the OP should define a new class that encapsulates the parameters
In these situations collections.namedtuple might turn out useful.
1

I think that usage of **kwarg is better. Look this example:

def MyFunc(**kwargs):
    print kwargs


MyFunc(par1=[1],par2=[2],par3=[1,2,3])

Comments

0

Usually, passing more than 3 parameters to a function is not recommended. This is not specific to python but to software design in general. You can read more about how to reduce the number of parameters passed to a function here.

Following the perspective of previous answers, but from a more general point of view I would like to add that there are several ways to make your code more readable:

  • to divide your function in simpler ones which have fewer arguments (define a function that takes your variable link, specific_list, list_type. By doing this you can detect within your WorkDetails function which list you passed with list_type and add the correct elements to that specific list)
  • to create a parameter object/data structure which is passed to your function (this is what previous answers suggested using lists, dictionaries...)

Hope this help.

Comments

0

That you need to pass that many lists is a sign that your function is not doing just one thing and you should refactor it by breaking it into smaller functions and/or converting it to a class. You can pass parameters as keywords, or pass an arbitrary number of parameters to a function, as described by this StackOverflow page, but it'll still be hard for others to read and understand if you have your function do more than one thing.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.