13

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?

jchanger
  • 739
  • 10
  • 29
Invictus
  • 4,028
  • 10
  • 50
  • 80

6 Answers6

21

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
NerdOnTour
  • 634
  • 4
  • 15
imanzabet
  • 2,752
  • 2
  • 26
  • 19
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

sampson-chen
  • 45,805
  • 12
  • 84
  • 81
2

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)
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])
crow16384
  • 587
  • 3
  • 15
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.

Community
  • 1
  • 1
jchanger
  • 739
  • 10
  • 29
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.

Max
  • 2,036
  • 2
  • 18
  • 27