1

Okay this one is confusing. My old piece of code has something like

map(lambda x:x.func1(arg1), other_args_to_be_mapped)

now I would like to make arg1 -> *args

while other_args_to_be_mapped stays unchanged.

in func1, the length of arguments will be checked different operations. My questions are

1) which length will be checked? arg1 or other_args_to_be_mapped

2) in func1, how should I set up the default? It was like

def func1(arg1=something)

but now with potential multiple arguments, I don't know what to do with the initialization. I want to be able to do something like

def func1(args*=something, something_else)

Is that even possible?

JChao
  • 2,178
  • 5
  • 35
  • 65
  • 1
    I don't understand what you're asking. "arg1->*args" what does that mean? Could you provide a **concrete example** of what you have and what you want it to do? – en_Knight Dec 18 '15 at 19:53
  • It's simply changing `arg1` (which is a single arg) to `*args` (which can be one or multiple arguments based on inputs) – JChao Dec 18 '15 at 20:17
  • Can you provide a concrete example of what you're trying to do. Something I can plug into a script and run. http://stackoverflow.com/help/mcve – en_Knight Dec 18 '15 at 20:22

1 Answers1

1

If I understand your question correctly, you're looking for variable arguments. These can be mixed with fixed arguments, provided you obey a logical ordering (fixed arguments first, then keyword arguments or variable arguments).

For example, the following shows how map to a function that takes in one constant argument and one variable argument. If you would like different behaviour, please provide a concrete example of what you are trying to accomplish

import random

class Foo:

    def get_variable_parameters(self):
        return [1] if random.random() > .5 else [1,2]

    def foo( self, arg, *args ):

        print("Doing stuff with constant arg", arg)

        if len(args) == 1:
            print("Good",args)
        else:
            print("Bad",args)

list(map( lambda x : x.foo( 'Static Argument', *x.get_variable_parameters()), [Foo(),Foo(),Foo()] ))

We don't know how many arguments are going to be passed to foo (in this trivial case, it's one or two), but the "*" notation accepts any number of objects to be passed

Note I've encapsulated map in list so that it gets evaluated, as in python3 it is a generator. List comprehension may be more idiomatic in python. Also don't forget you can always use a simple for loop - an obfuscated or complex map call is far less pythonic than a clear (but several line) for-loop, imo.

If, rather, you're trying to combine multiple arguments in a map call, I would recommend using the same variable argument strategy with the zip function, e.g.,

def foo(a,*b): ...
map(lambda x : foo(x[0],*x[1]), zip(['a','b'],[ [1], [1,2] ]))

In this case, foo will get called first as foo('a',1), and then as foo('b',2,3)

Community
  • 1
  • 1
en_Knight
  • 5,301
  • 2
  • 26
  • 46
  • sorry but I can't provide the code as it's part of something else and I don't think I have permission to do it. I'll think about how I can make it more clear though. Thanks for your answer – JChao Dec 18 '15 at 20:26
  • You don't have to provide your production code, just create a minimal working example of what you're trying to accomplish – en_Knight Dec 18 '15 at 20:29