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.
Related
This question already has answers here:
How to create a "singleton" tuple with only one element
(4 answers)
Closed 3 years ago.
Why type((1)) is int and not a tuple? Whereas type((1,)) gives tuple.
That's also an answer to the question why we should use commas while defining a tuple with one value. Because tuples are not like lists which is unique in a way that we define it (using squared brackets) we have to add the comma to the value. In the first one type((1)) inner paranthesis have no effect, so it's just a basic integer nothing else. Like when you define expressions in paranthesis to give them priority. Hope it helps :)
Python compiler treated (1) as 1 because of that it is showing as int. that is inbuilt behavior of python compiler.
>>> a = (1)
>>> print(a)
1
>>> a = (1,)
>>> print(a)
(1,)
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)
This question already has answers here:
How do Python's any and all functions work?
(10 answers)
Closed 5 years ago.
is there a way in python to check the logical operator AND with variable number of arguments. for example:
def and_function(a,b,c,d,e....):
if a and b and c and d and c and d and e and . and . is True:
return True
i see that this is possible using *args function and using a counter. But wish to know if there is a better way of doing it.
You basically want all() but to customize it you can use this:
def and_function(*args):
return all([a > 5 for a in args])
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)