This question already has answers here:
Unpacking arguments: only named arguments may follow *expression
(6 answers)
Closed 3 years ago.
I have the following code to use * argument for a function.
inputs = [fill(input) for input in input_shapes]
# num_runs is an integer
def bench(num_runs):
inputs.append(num_runs) # can I remove this?
handle_type(*inputs)
del inputs[-1] # can I remove this?
I want to know a better way to handle *inputs, so I don't have to call append and del every time.
I tried a simple example:
inputs = [1, 2, 3]
inputs2 = [1, 2]
def Test(a, b, c):
print (a, b, c)
Test(*inputs) # works
Test(*inputs2, 3) # SyntaxError: only named arguments may follow *expression
I found a solution here Unpacking arguments: only named arguments may follow *expression and it is what I am looking for.
You should be able to do this, at least in reasonably recent Python 3 versions:
inputs = [fill(input) for input in input_shapes]
def bench(num_runs):
handle_type(*inputs, num_runs)
Related
This question already has answers here:
What does the "at" (#) symbol do in Python?
(14 answers)
How do I make function decorators and chain them together?
(20 answers)
Closed 26 days ago.
#the code given is:
def f(a):
print('hello')
#f
def f(a,b):
return a%b
f(4,0)
What I expected to happen was a zero division error, instead it printed hello.
When I write the same code without '#f'
it gives the expected result as output
I've never seen symbol/expression being used in python
This is new and Google too has nothing about it
Decorator syntax is a shorthand for a particular function application.
#f
def f(a, b):
return a%b
is roughly equivalent to
def tmp(a, b):
return a % b
tmp2 = f(tmp)
f = tmp2
(Reusing the name f for everything makes this tricker to understand.)
First, your division-by-zero function is defined. Next, your original function f is called: it prints hello and returns None. Finally, you attempt to call None with two arguments, but it isn't callable, resulting in the TypeError you allude to.
In short, the decorator syntax takes care of treating all the things that would otherwise have been named f as distinct objects and applying things in the correct order.
This question already has answers here:
What does ** (double star/asterisk) and * (star/asterisk) do for parameters?
(25 answers)
Closed 7 years ago.
I'm learning formatting expressions from a book and i have a question:
'{num} = {title}'.format(**dict(num=7, title='Strings'))
in the line above why are there two * before dict?? what do they represent?
the book didn't even mention this type of formatting expression and suddenly it was in the examples!!
The Principles
Python functions allow keyword arguments. For example this function:
def sub(a, b):
return a - b
can be called like this:
>>> sub(b=10, a=4)
-6
If you have the arguments in a dictionary:
>>> args = {'a': 4, 'b': 10}
you can use the ** syntax to achieve the same:
>>> sub(**args)
-6
This is called unpacking because the items in the dictionary are used individually as arguments.
Your Example
Your example is over complicated. This would work:
'{num} = {title}'.format(num=7, title='Strings')
No need for using ** and a dictionary. The format() methods works like normal function and can be used with keyword arguments directly. The values 7 and Strings are put into a dictionary just be taken out again immediately.
This question already has answers here:
Pass a list to a function to act as multiple arguments [duplicate]
(3 answers)
Closed 9 years ago.
Is it possible to unpack a list or tuple such that the values can be used as function parameters? I.e., how can I make the second line work?
f(1,2,3)
f(???([1,2,3]))
I'm currently doing this by hand, something like:
tmp1, tmp2, tmp3 = [1,2,3]
f(tmp1,tmp2,tmp3)
context: I don't have the ability to modify f(), but this is part of a code generator so funky solutions are not a problem.
Yes, you can use the *args (splat) syntax:
f(*[1, 2, 3])
See the call expressions documentation.
There is a keyword-parameter equivalent too, using two stars:
kwargs = {'foo': 'bar', 'spam': 'ham'}
f(**kwargs)
and there is equivalent syntax for specifying catch-all arguments in a function signature:
def func(*args, **kw):
# args now holds positional arguments, kw keyword arguments
This question already has answers here:
Use of *args and **kwargs [duplicate]
(11 answers)
Closed 9 years ago.
as I was wondering how tuple unpacking was working, I've found on several threads this answer as an alternative to slicing :
>>>>def unpack(first,*rest):
return first, rest
which works as follows:
>>>>first,rest=unpack(*(1,2,3))
>>>>first
1
>>>>rest
(2,3)
I don't understand how the * works. The argument "first" isn't supposed to be given to my function unpack ? I thought * meant that the argument was optional.
Thanks for your help
* in a function definition doesn't mean optional; it means "pack any additional (non-keyword) arguments the caller supplied into a tuple and put the tuple here". Similarly, * on a function call means "unpack this sequence of things and supply all the elements as arguments to the function individually."
unpack(*(1,2,3))
unpacks (1,2,3) and calls
unpack(1,2,3)
1 is assigned to first, and the remaining arguments 2 and 3 are packed into a tuple and assigned to rest.
In your case, unpack(*(1,2,3)) is just unpack(1, 2, 3).
Implementation of unpack takes the first argument, and an args tale, then returns it as a tuple.
Star syntax is useful, if you would pass arguments as a variable:
a = (1, 2, 3)
first, rest = unpack(*a)
This question already has answers here:
Pass a list to a function to act as multiple arguments [duplicate]
(3 answers)
Closed 9 years ago.
I am writing a little script in which I call itertools.product like so:
for p in product(list1,list2,list3):
self.createFile(p)
Is there a way for me to call this function without knowing in advance how many lists to include?
Thanks
You can use the star or splat operator (it has a few names): for p in product(*lists) where lists is a tuple or list of things you want to pass.
def func(a,b):
print (a,b)
args=(1,2)
func(*args)
You can do a similar thing when defining a function to allow it to accept a variable number of arguments:
def func2(*args): #unpacking
print(args) #args is a tuple
func2(1,2) #prints (1, 2)
And of course, you can combine the splat operator with the variable number of arguments:
args = (1,2,3)
func2(*args) #prints (1, 2, 3)
Use the splat operator(*) to pass and collect unknown number of arguments positional arguments.
def func(*args):
pass
lis = [1,2,3,4,5]
func(*lis)