*args vs list as a arguments in Python [duplicate] - python

This question already has answers here:
What does ** (double star/asterisk) and * (star/asterisk) do for parameters?
(25 answers)
Closed 3 years ago.
I just want to understand why we use *args when the same work can be done by list when we pass it as a argument. In which scenarios do we really need *args, where list as a argument will fail to do that operation.
list =[1,2,3,4,5,6,7]
def method1(args):
for i in args:
print(i*2)
method1(list)
list =[1,2,3,4,5,6,7]
def method1(*args):
for i in args:
print(i*2)
method1(*list)
I didn't find any differences. Please correct me if i am wrong.

def method1(args):
print(args)
method1(5) it will print 5
method1() method1() missing 1 required positional argument: 'args'
method1(2,6) TypeError: method1() takes 1 positional argument but 2 were given
To Avoid this situation we use
def method1(*args):
print(args)
method1(1, 2, '3')
(1, 2, '3') print this
So *args is useful when we don’t know in advance how many arguments we need to pass in.

The difference is that you can pass any number of arguments in the second case where it will throw error in the first case.
Case 1:
lst = [1,2,3,4,5,6,7]
a = 1
b = 2
def method1(args):
for i in args:
print(i*2)
method1(lst, a, b)
...fails with 'TypeError: method1() takes 1 positional argument but 3 were given'.
Case 2 (i):
lst = [1,2,3,4,5,6,7]
a = 1
def method1(*args):
for i in args:
print(i*2)
method1(lst, a)
...works.
Case 2 (ii):
lst = [1,2,3,4,5,6,7]
a = 1
b = 2
def method1(*args):
for i in args:
print(i*2)
method1(lst, a, b)
...works and so on, you can pass any number of arguments.

Related

What does * represent in function argument list in python? [duplicate]

This question already has answers here:
What does ** (double star/asterisk) and * (star/asterisk) do for parameters?
(25 answers)
understanding '*' "keyword only" argument notation in python3 functions [duplicate]
(2 answers)
Closed 3 years ago.
While going through the source code, I noticed the following syntax being used in the asyncio library:
#coroutine
def sleep(delay, result=None, *, loop=None):
"""Coroutine that completes after a given time (in seconds)."""
if delay == 0:
yield
return result
if loop is None:
loop = events.get_event_loop()
future = loop.create_future()
h = future._loop.call_later(delay,
futures._set_result_unless_cancelled,
future, result)
try:
return (yield from future)
finally:
h.cancel()
what does the * do in the argument list?
It means that parameter(s) that comes after * are keyword only parameters.
Consider the following:
def test(delay, result=None, *, loop=None):
print(delay, result, loop)
In this case, test(1,2,2) will raise TypeError since it is expecting at most two positional arguments, i.e. delay and result:
test(1,2,2)
TypeError: test() takes from 1 to 2 positional arguments but 3 were given
The third argument, or loop, can only be assigned if used as keyword:
test(1,2,loop=2)
# 1 2 2
# Works fine
For more detail, refer to Function Definitions

* mark in print function call [duplicate]

This question already has answers here:
What does ** (double star/asterisk) and * (star/asterisk) do for parameters?
(25 answers)
Closed 6 years ago.
What is this star mark in this print function call?
for i in range(int(input())):
s=input()
print(*["".join(s[::2]),"".join(s[1::2])])
It is called argument unpacking. If you were to omit it, then it would only give the list created by the list comprehension to the print function as one argument. With the asterisk it passes every item in that list as separate argument.
Consider this example:
def my_func(arg1, arg2, arg3):
print('yay it worked')
and then call it with:
my_func(*[1, 2, 3])
that way arg1 will be 1, arg2 will be 2 and arg3 will be 3.
If you change the call to:
my_func([1, 2, 3])
then you pass the list to arg1 and it will raise a TypeError because it's missing two positional arguments.

python passing positional arguments to another function call [duplicate]

This question already has answers here:
What does ** (double star/asterisk) and * (star/asterisk) do for parameters?
(25 answers)
What do *args and **kwargs mean? [duplicate]
(5 answers)
Closed 9 years ago.
Can someone please explain to me how the below works:
class Memoize:
def __init__(self, f):
self.f = f
self.memo = {}
def __call__(self, *args):
if not args in self.memo:
self.memo[args] = self.f(*args)
return self.memo[args]
Then:
def factorial(k):
if k < 2: return 1
return k * factorial(k - 1)
factorial = Memoize(factorial)
This is taken from this question. I would like to understand how does self.f(*args) work. args is a tuple of positional arguments. When I try to do:
*(1,2,3)
I get syntax error. I thought it's some kind on unpacking operator or something like that. Does asterisk with a tuple mean anything independently or does it exist only in the context of a function call? Thank you for any explanations.
It /is/ an unpacking operator. However, it doesn't always work that way when called directly in the interpreter. Check this out:
In [90]: def addThese(a,b,c):
....: print 'a', a
....: print 'b', b
....: print 'c', c
....: print 'a+b+c', a+b+c
....: return a+b+c
....:
In [91]: args = (1,3,5)
In [92]: addThese(1,3,5)
a 1
b 3
c 5
a+b+c 9
Out[92]: 9
In [93]: addThese(args)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-93-cc47562f352a> in <module>()
----> 1 addThese(args)
TypeError: addThese() takes exactly 3 arguments (1 given)
In [94]: addThese(*args)
a 1
b 3
c 5
a+b+c 9
Out[94]: 9

optional arguments function

I am searching how I could use optional arguments in python.
I have read this question but it is not clear to me.
Lets say I have a function f that can take 1 or more arguments to understand time series. Am i obliged to specify the number of arguments and set default values for each argument?
What I aim to do is being able to write a function this way:
simple function:
def f(x,y):
return x + y
#f(1,2) returns 3
What i want is also f(1,2,3) to return me 6 and f(7) returning me 7
Is it possible to write it without setting a predefined number of mandatory/optional parameters?
Is it possible to write it without having to set default values to 0 ?
How to write this function?
Its a simple example with numbers but the function i need to write is comparing a set of successive objects. After comparison is done, the data set will feed a neural network.
Thanks for reading.
EDIT:
Objects I am feeding my function with are tuples like this (float,float,float,bool,string)
You can put *args in your function and then take arbitrary (non-keyword) arguments. *args is a tuple, so you can iterate over it like any Python tuple/list/iterable. IE:
def f(*args):
theSum = 0
for arg in args:
theSum += arg
return theSum
print f(1,2,3,4)
def f(*args):
"""
>>> f(1, 2)
3
>>> f(7)
7
>>> f(1, 2, 3)
6
>>> f(1, 2, 3, 4, 5, 6)
21
"""
return sum(args)
If you need to do something more complicated than sum you could just iterate over args like this:
def f(*args):
r = 0
for arg in args:
r += arg
return r
See this question for more information on *args and **kwargs
Also see this sections on the Python tutorial: Arbitray Argument List
You can use the follow syntax:
def f(*args):
return sum(args)
The * before args tells it to "swallow up" all arguments, makng args a tuple. You can also mix this form with standard arguments, as long as the *args goes last. For example:
def g(a,b,*args):
return a * b * sum(args)
The first example uses the built-in sum function to total up the arguments. sum takes a sequence as adds it up for you:
>>> sum([1,3,5])
9
>>> sum(range(100))
4950
The args name is not mandatory but is used by convention so best to stick with it. There is also **kwargs for undefined keyword arguments.

What does asterisk * mean in Python? [duplicate]

This question already has answers here:
What does ** (double star/asterisk) and * (star/asterisk) do for parameters?
(25 answers)
Closed 9 years ago.
Does * have a special meaning in Python as it does in C? I saw a function like this in the Python Cookbook:
def get(self, *a, **kw)
Would you please explain it to me or point out where I can find an answer (Google interprets the * as wild card character and thus I cannot find a satisfactory answer).
See Function Definitions in the Language Reference.
If the form *identifier is
present, it is initialized to a tuple
receiving any excess positional
parameters, defaulting to the empty
tuple. If the form **identifier is
present, it is initialized to a new
dictionary receiving any excess
keyword arguments, defaulting to a new
empty dictionary.
Also, see Function Calls.
Assuming that one knows what positional and keyword arguments are, here are some examples:
Example 1:
# Excess keyword argument (python 2) example:
def foo(a, b, c, **args):
print "a = %s" % (a,)
print "b = %s" % (b,)
print "c = %s" % (c,)
print args
foo(a="testa", d="excess", c="testc", b="testb", k="another_excess")
As you can see in the above example, we only have parameters a, b, c in the signature of the foo function. Since d and k are not present, they are put into the args dictionary. The output of the program is:
a = testa
b = testb
c = testc
{'k': 'another_excess', 'd': 'excess'}
Example 2:
# Excess positional argument (python 2) example:
def foo(a, b, c, *args):
print "a = %s" % (a,)
print "b = %s" % (b,)
print "c = %s" % (c,)
print args
foo("testa", "testb", "testc", "excess", "another_excess")
Here, since we're testing positional arguments, the excess ones have to be on the end, and *args packs them into a tuple, so the output of this program is:
a = testa
b = testb
c = testc
('excess', 'another_excess')
You can also unpack a dictionary or a tuple into arguments of a function:
def foo(a,b,c,**args):
print "a=%s" % (a,)
print "b=%s" % (b,)
print "c=%s" % (c,)
print "args=%s" % (args,)
argdict = dict(a="testa", b="testb", c="testc", excessarg="string")
foo(**argdict)
Prints:
a=testa
b=testb
c=testc
args={'excessarg': 'string'}
And
def foo(a,b,c,*args):
print "a=%s" % (a,)
print "b=%s" % (b,)
print "c=%s" % (c,)
print "args=%s" % (args,)
argtuple = ("testa","testb","testc","excess")
foo(*argtuple)
Prints:
a=testa
b=testb
c=testc
args=('excess',)
I only have one thing to add that wasn't clear from the other answers (for completeness's sake).
You may also use the stars when calling the function. For example, say you have code like this:
>>> def foo(*args):
... print(args)
...
>>> l = [1,2,3,4,5]
You can pass the list l into foo like so...
>>> foo(*l)
(1, 2, 3, 4, 5)
You can do the same for dictionaries...
>>> def foo(**argd):
... print(argd)
...
>>> d = {'a' : 'b', 'c' : 'd'}
>>> foo(**d)
{'a': 'b', 'c': 'd'}
All of the above answers were perfectly clear and complete, but just for the record I'd like to confirm that the meaning of * and ** in python has absolutely no similarity with the meaning of similar-looking operators in C.
They are called the argument-unpacking and keyword-argument-unpacking operators.
A single star means that the variable 'a' will be a tuple of extra parameters that were supplied to the function. The double star means the variable 'kw' will be a variable-size dictionary of extra parameters that were supplied with keywords.
Although the actual behavior is spec'd out, it still sometimes can be very non-intuitive. Writing some sample functions and calling them with various parameter styles may help you understand what is allowed and what the results are.
def f0(a)
def f1(*a)
def f2(**a)
def f3(*a, **b)
etc...
I find * useful when writing a function that takes another callback function as a parameter:
def some_function(parm1, parm2, callback, *callback_args):
a = 1
b = 2
...
callback(a, b, *callback_args)
...
That way, callers can pass in arbitrary extra parameters that will be passed through to their callback function. The nice thing is that the callback function can use normal function parameters. That is, it doesn't need to use the * syntax at all. Here's an example:
def my_callback_function(a, b, x, y, z):
...
x = 5
y = 6
z = 7
some_function('parm1', 'parm2', my_callback_function, x, y, z)
Of course, closures provide another way of doing the same thing without requiring you to pass x, y, and z through some_function() and into my_callback_function().

Categories