what is the asterisk in "replace(*something)" for? (python) [duplicate] - python

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
What does *args and **kwargs mean?
I' just reading Mining the social web and encountered a python syntax that I can't figure out:
transforms = [(', Inc.', ''), (', Inc', ''), (', LLC', ''), (', LLP', '')]
"google, Inc.".replace(*transforms[0])
But if I type
*transforms[0]
in the interpreter, it says it is invalid syntax. I googled it, but the python docu really is not up for the job.
So what does the asterisk means here please? Thank you all.

The *argument format in python means: use all elements in the sequence argument and pass them as arguments to the function.
In this specific case, that translates to:
"google, Inc.".replace(', Inc.', '')
This is easiest demonstrated:
>>> def foo(arg1, arg2):
... print arg1, arg2
...
>>> arguments = ('spam', 'eggs')
>>> foo(*arguments)
spam, eggs
You can also use the **kw double star format to pass in keyword arguments:
>>> def foo(arg1='ham', arg2='spam'):
... print arg1, arg2
...
>>> arguments = dict(arg2='foo', arg1='bar')
>>> foo(**arguments)
bar, foo
and you can use the same spelling in a function definition to capture arbitrary positional and keyword arguments:
>>> def foo(*args, **kw):
... print args, kw
...
>>> foo('arg1', 'arg2', foo='bar', spam='eggs')
('arg1', 'arg2'), {'foo': 'bar', 'spam': 'eggs'}

The asterisk unpacks an iterable. I think it is best explained with an example:
>>> def exampleFunction (paramA, paramB, paramC):
print('A:', paramA)
print('B:', paramB)
print('C:', paramC)
>>> myTuple = ('foo', 'bar', 'baz')
>>> myTuple
('foo', 'bar', 'baz')
>>> exampleFunction(myTuple)
Traceback (most recent call last):
File "<pyshell#8>", line 1, in <module>
exampleFunction(myTuple)
TypeError: exampleFunction() takes exactly 3 arguments (1 given)
>>> exampleFunction(myTuple[0], myTuple[1], myTuple[2])
A: foo
B: bar
C: baz
>>> exampleFunction(*myTuple)
A: foo
B: bar
C: baz
As you can see, we defined a function that takes three arguments and a tuple with three elements. Now if we want to use the values from the tuple directly, we cannot just pass the tuple and have it working. We could pass each element separately but that is just very verbose. What we do instead is use the asterisk to unpack the tuple and essentially use the elements from the tuple as arguments.
There is a second usage for the unpacking functionality when working with a unknown number of parameters:
>>> def example2 (*params):
for param in params:
print(param)
>>> example2('foo')
foo
>>> example2('foo', 'bar')
foo
bar
>>> example2(*myTuple)
foo
bar
baz
The asterisk allows us here to define a parameter that takes all the remaining values that were passed and packs it into an iterable, so we can iterate it.

It turns the tuple passed into a list of arguments. So
"google, Inc.".replace(*transforms[0])
becomes
"google, Inc.".replace(', Inc.', '')
This way you can programatically construct the list of arguments that are being passed (with variable length being a key advantage).

Check section 4.7.4 of the Python tutorial: http://docs.python.org/tutorial/controlflow.html#more-on-defining-functions
But if I type
*transforms[0]
in the interpreter, it says it is invalid syntax.
The * in front of transforms[0] only has meaning in a function call.
An alternative way of making this call with the data in the first tuple in the list is:
"Google, Inc.".replace(transforms[0][0],transforms[0][1])

Related

*_ and *args assigns which value at runtime | python |

Not getting internally what is happening. *_ amd *args doing
what is assigned to default() at runtime
Using *_ in default
def default(*_):
return "Not Happy"
a,b=10,20
default(a,b)
Using *args in default
def default(*args):
return "Not Happy"
a,b=10,20
default(a,b)
I am trying to understand what is assigned to default at runtime.
if not a and b
I have used website to see visually what happens at runtime during execution but not getting : https://pythontutor.com/visualize.html
In Python, you can define variadic functions (i.e. functions that can take any number of arguments), cf the tutorial or a RealPython article about it.
The gist of it is that you can declare a *whatever parameter, and Python will collect the variadic parameters and put them in there for you. For example :
>>> def foo(*args):
>>> print(type(args), args)
>>>
>>> foo()
<class 'tuple'> ()
>>> foo(1)
<class 'tuple'> (1,)
>>> foo(1, 'a')
<class 'tuple'> (1, 'a')
>>> foo(1, 'a', 'b', 'c')
<class 'tuple'> (1, 'a', 'b', 'c')
The convention is to call it args, but you can give it another name :
>>> def foo(*elephant):
>>> print(elephant)
>>>
>>> foo(1, 'a')
(1, 'a')
So when you call default(a,b), then *args (or *_ if you want) is filled, and you can use it in your function :
>>> def default(*args):
>>> return "Not Happy" + str(args)
>>>
>>> a,b=10,20
>>> default(a,b)
'Not Happy(10, 20)'
default is a function, when you do default(...) you call that function, meaning you execute the code you wrote in it. You are passing a and b, none of them is listed as a regular parameter, so both ends up in the *args parameter.

Why would you create a variable in a function call? [duplicate]

How are "keyword arguments" different from regular arguments? Can't all arguments be passed as name=value instead of using positional syntax?
There are two related concepts, both called "keyword arguments".
On the calling side, which is what other commenters have mentioned, you have the ability to specify some function arguments by name. You have to mention them after all of the arguments without names (positional arguments), and there must be default values for any parameters which were not mentioned at all.
The other concept is on the function definition side: you can define a function that takes parameters by name -- and you don't even have to specify what those names are. These are pure keyword arguments, and can't be passed positionally. The syntax is
def my_function(arg1, arg2, **kwargs)
Any keyword arguments you pass into this function will be placed into a dictionary named kwargs. You can examine the keys of this dictionary at run-time, like this:
def my_function(**kwargs):
print str(kwargs)
my_function(a=12, b="abc")
{'a': 12, 'b': 'abc'}
There is one last language feature where the distinction is important. Consider the following function:
def foo(*positional, **keywords):
print "Positional:", positional
print "Keywords:", keywords
The *positional argument will store all of the positional arguments passed to foo(), with no limit to how many you can provide.
>>> foo('one', 'two', 'three')
Positional: ('one', 'two', 'three')
Keywords: {}
The **keywords argument will store any keyword arguments:
>>> foo(a='one', b='two', c='three')
Positional: ()
Keywords: {'a': 'one', 'c': 'three', 'b': 'two'}
And of course, you can use both at the same time:
>>> foo('one','two',c='three',d='four')
Positional: ('one', 'two')
Keywords: {'c': 'three', 'd': 'four'}
These features are rarely used, but occasionally they are very useful, and it's important to know which arguments are positional or keywords.
Using keyword arguments is the same thing as normal arguments except order doesn't matter. For example the two functions calls below are the same:
def foo(bar, baz):
pass
foo(1, 2)
foo(baz=2, bar=1)
Positional Arguments
They have no keywords before them. The order is important!
func(1,2,3, "foo")
Keyword Arguments
They have keywords in the front. They can be in any order!
func(foo="bar", baz=5, hello=123)
func(baz=5, foo="bar", hello=123)
You should also know that if you use default arguments and neglect to insert the keywords, then the order will then matter!
def func(foo=1, baz=2, hello=3): ...
func("bar", 5, 123)
There are two ways to assign argument values to function parameters, both are used.
By Position. Positional arguments do not have keywords and are assigned first.
By Keyword. Keyword arguments have keywords and are assigned second, after positional arguments.
Note that you have the option to use positional arguments.
If you don't use positional arguments, then -- yes -- everything you wrote turns out to be a keyword argument.
When you call a function you make a decision to use position or keyword or a mixture. You can choose to do all keywords if you want. Some of us do not make this choice and use positional arguments.
I'm surprised that no one seems to have pointed out that one can pass a dictionary of keyed argument parameters, that satisfy the formal parameters, like so.
>>> def func(a='a', b='b', c='c', **kwargs):
... print 'a:%s, b:%s, c:%s' % (a, b, c)
...
>>> func()
a:a, b:b, c:c
>>> func(**{'a' : 'z', 'b':'q', 'c':'v'})
a:z, b:q, c:v
>>>
Using Python 3 you can have both required and non-required keyword arguments:
Optional: (default value defined for param 'b')
def func1(a, *, b=42):
...
func1(value_for_a) # b is optional and will default to 42
Required (no default value defined for param 'b'):
def func2(a, *, b):
...
func2(value_for_a, b=21) # b is set to 21 by the function call
func2(value_for_a) # ERROR: missing 1 required keyword-only argument: 'b'`
This can help in cases where you have many similar arguments next to each other especially if they are of the same type, in that case I prefer using named arguments or I create a custom class if arguments belong together.
I'm surprised no one has mentioned the fact that you can mix positional and keyword arguments to do sneaky things like this using *args and **kwargs (from this site):
def test_var_kwargs(farg, **kwargs):
print "formal arg:", farg
for key in kwargs:
print "another keyword arg: %s: %s" % (key, kwargs[key])
This allows you to use arbitrary keyword arguments that may have keys you don't want to define upfront.
I was looking for an example that had default kwargs using type annotation:
def test_var_kwarg(a: str, b: str='B', c: str='', **kwargs) -> str:
return ' '.join([a, b, c, str(kwargs)])
example:
>>> print(test_var_kwarg('A', c='okay'))
A B okay {}
>>> d = {'f': 'F', 'g': 'G'}
>>> print(test_var_kwarg('a', c='c', b='b', **d))
a b c {'f': 'F', 'g': 'G'}
>>> print(test_var_kwarg('a', 'b', 'c'))
a b c {}
Just suplement/add a way for defining the default value of arguments that is not assigned in key words when calling the function:
def func(**keywargs):
if 'my_word' not in keywargs:
word = 'default_msg'
else:
word = keywargs['my_word']
return word
call this by:
print(func())
print(func(my_word='love'))
you'll get:
default_msg
love
read more about *args and **kwargs in python: https://www.digitalocean.com/community/tutorials/how-to-use-args-and-kwargs-in-python-3

Difference call function with asterisk parameter and without

I know what the meaning of an asterisk is in a function definition in Python.
I often, though, see asterisks for calls to functions with parameters like:
def foo(*args, **kwargs):
first_func(args, kwargs)
second_func(*args, **kwargs)
What is the difference between the first and the second function call?
Let args = [1,2,3]:
func(*args) == func(1,2,3) - variables are unpacked out of list (or any other sequence type) as parameters
func(args) == func([1,2,3]) - the list is passed
Let kwargs = dict(a=1,b=2,c=3):
func(kwargs) == func({'a':1, 'b':2, 'c':3}) - the dict is passed
func(*kwargs) == func(('a','b','c')) - tuple of the dict's keys (in random order)
func(**kwargs) == func(a=1,b=2,c=3) - (key, value) are unpacked out of the dict (or any other mapping type) as named parameters
The difference is how the arguments are passed into the called functions. When you use the *, the arguments are unpacked (if they're a list or tuple)—otherwise, they're simply passed in as is.
Here's an example of the difference:
>>> def add(a, b):
... print a + b
...
>>> add(*[2,3])
5
>>> add([2,3])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: add() takes exactly 2 arguments (1 given)
>>> add(4, 5)
9
When I prefixed the argument with *, it actually unpacked the list into two separate arguments, which were passed into add as a and b. Without it, it simply passed in the list as a single argument.
The same is the case for dictionaries and **, except they're passed in as named arguments rather than ordered arguments.
>>> def show_two_stars(first, second='second', third='third'):
... print "first: " + str(first)
... print "second: " + str(second)
... print "third: " + str(third)
>>> show_two_stars('a', 'b', 'c')
first: a
second: b
third: c
>>> show_two_stars(**{'second': 'hey', 'first': 'you'})
first: you
second: hey
third: third
>>> show_two_stars({'second': 'hey', 'first': 'you'})
first: {'second': 'hey', 'first': 'you'}
second: second
third: third
def fun1(*args):
""" This function accepts a non keyworded variable length argument as a parameter.
"""
print args
print len(args)
>>> a = []
>>> fun1(a)
([],)
1
# This clearly shows that, the empty list itself is passed as a first argument. Since *args now contains one empty list as its first argument, so the length is 1
>>> fun1(*a)
()
0
# Here the empty list is unwrapped (elements are brought out as separate variable length arguments) and passed to the function. Since there is no element inside, the length of *args is 0
>>>

Automatically remove named parameters from a Python function call

I've written a Python library that uses a lot of named parameters in its function calls, and I'm wondering if there's any way to automatically remove all of these named parameters, instead of removing them manually (which is a very tedious task).
For example, would it be possible to translate this function call:
getClass(lang="Java", body=[
mainMethod(lang="Java", body=[
println(lang="Java", toPrint="Hello World")
])
])
into the function call below (which omits the named arguments, and is much more concise?):
getClass("Java", [
mainMethod("Java", [
println("Java", "Hello World!")
])
])
In order to do this, one possible approach would be to write a function that would print its own function call as a string - however, I don't think it's possible to write a function that would do this. Are there any other approaches to this problem that might work as well?
There is no need. Keyword arguments can still be passed positionally. There is the added benefit, here, of being able to specify one or none of them, if you would so please. However, you don't need to specify any at all.
>>> def foo(bar=1, baz=[2,3]):
... print bar, baz
...
>>> foo()
1 [2, 3]
>>> foo(baz=4)
1 4
>>> foo(10, 20)
10 20
If I'm misunderstanding the code you're providing, let me know. Steve's answer seems to indicate that you are actually working with strings, but I didn't see anything in your post to indicate that.
You did mention a function which prints its own function call; by this, I assume you mean that the function must print a string which looks exactly like the thing you'd type to call the function with the same arguments which you passed. This is relatively easy to do, because you can either type the function's name as-is, or you can use its __name__ attribute.
>>> def goo(a,b):
... print "{}({}, {})".format(goo.__name__, a, b)
...
>>> goo(1,2)
goo(1, 2)
>>> def hoo(*args):
... print "{}({})".format(hoo.__name__, ', '.join((str(arg) for arg in args)))
...
>>>
>>> hoo(2,3,4,5)
hoo(2, 3, 4, 5)
Thinking about it, your example seems wanting of a general function which would grant this behavior to any function - recursively. Here's a way to achieve that, using partials (I'll redefine foo() so that the example makes some more sense):
>>> from functools import partial
>>> def foo(a, b):
... return (a if not isinstance(a, partial) else a()) + (b if not isinstance(b, partial) else b())
...
>>> fun = partial(foo, 1, partial(foo, partial(foo, 2, 4), partial(foo, 3, 5)))
>>> fun()
15
>>> fun = partial(foo, 1, partial(foo, partial(foo, 2, 4), partial(foo, 3, 5)))
>>> def print_pfunc(pfunc):
... return "{}({}{}{})".format(pfunc.func.__name__, ', '.join(str(arg) if not isinstance(arg, partial) else print_pfunc(arg) for arg in pfunc.args) if pfunc.args else '', ', ' if pfunc.args and pfunc.keywords else '', ', '.join('{}={}'.format(k, v if not isinstance(v, partial) else print_pfunc(v)) for k, v in pfunc.keywords) if pfunc.keywords else '')
...
>>> print print_pfunc(fun)
foo(1, foo(foo(2, 4), foo(3, 5)))
If you're not a fan of that very long format() call, here's a different way to write it (just so that you don't have to spend time decoding my garbage):
def print_pfunc(pfunc):
args = ""
if pfunc.args is not None:
args = ', '.join(str(arg) if not isinstance(arg, partial) else print_pfunc(arg) for arg in pfunc.args)
kwargs = ""
if pfunc.keywords is not None:
kwargs = ', '.join('{}={}'.format(k, v if not isinstance(v, partial) else print_pfunc(v)) for k, v in pfunc.keywords)
return "{}({}{}{})".format(pfunc.func.__name__, args, ', ' if args and kwargs else '', kwargs)
Adapting this to your code, now, will require you to write code which will turn your function calls into partials before evaluating them. It's up to you what you want to do from this point - I can't think of a clever way to get around the fact that function calls passed as arguments get evaluated before they are passed, as this will interfere with what you are trying to do.

Normal arguments vs. keyword arguments

How are "keyword arguments" different from regular arguments? Can't all arguments be passed as name=value instead of using positional syntax?
There are two related concepts, both called "keyword arguments".
On the calling side, which is what other commenters have mentioned, you have the ability to specify some function arguments by name. You have to mention them after all of the arguments without names (positional arguments), and there must be default values for any parameters which were not mentioned at all.
The other concept is on the function definition side: you can define a function that takes parameters by name -- and you don't even have to specify what those names are. These are pure keyword arguments, and can't be passed positionally. The syntax is
def my_function(arg1, arg2, **kwargs)
Any keyword arguments you pass into this function will be placed into a dictionary named kwargs. You can examine the keys of this dictionary at run-time, like this:
def my_function(**kwargs):
print str(kwargs)
my_function(a=12, b="abc")
{'a': 12, 'b': 'abc'}
There is one last language feature where the distinction is important. Consider the following function:
def foo(*positional, **keywords):
print "Positional:", positional
print "Keywords:", keywords
The *positional argument will store all of the positional arguments passed to foo(), with no limit to how many you can provide.
>>> foo('one', 'two', 'three')
Positional: ('one', 'two', 'three')
Keywords: {}
The **keywords argument will store any keyword arguments:
>>> foo(a='one', b='two', c='three')
Positional: ()
Keywords: {'a': 'one', 'c': 'three', 'b': 'two'}
And of course, you can use both at the same time:
>>> foo('one','two',c='three',d='four')
Positional: ('one', 'two')
Keywords: {'c': 'three', 'd': 'four'}
These features are rarely used, but occasionally they are very useful, and it's important to know which arguments are positional or keywords.
Using keyword arguments is the same thing as normal arguments except order doesn't matter. For example the two functions calls below are the same:
def foo(bar, baz):
pass
foo(1, 2)
foo(baz=2, bar=1)
Positional Arguments
They have no keywords before them. The order is important!
func(1,2,3, "foo")
Keyword Arguments
They have keywords in the front. They can be in any order!
func(foo="bar", baz=5, hello=123)
func(baz=5, foo="bar", hello=123)
You should also know that if you use default arguments and neglect to insert the keywords, then the order will then matter!
def func(foo=1, baz=2, hello=3): ...
func("bar", 5, 123)
There are two ways to assign argument values to function parameters, both are used.
By Position. Positional arguments do not have keywords and are assigned first.
By Keyword. Keyword arguments have keywords and are assigned second, after positional arguments.
Note that you have the option to use positional arguments.
If you don't use positional arguments, then -- yes -- everything you wrote turns out to be a keyword argument.
When you call a function you make a decision to use position or keyword or a mixture. You can choose to do all keywords if you want. Some of us do not make this choice and use positional arguments.
I'm surprised that no one seems to have pointed out that one can pass a dictionary of keyed argument parameters, that satisfy the formal parameters, like so.
>>> def func(a='a', b='b', c='c', **kwargs):
... print 'a:%s, b:%s, c:%s' % (a, b, c)
...
>>> func()
a:a, b:b, c:c
>>> func(**{'a' : 'z', 'b':'q', 'c':'v'})
a:z, b:q, c:v
>>>
Using Python 3 you can have both required and non-required keyword arguments:
Optional: (default value defined for param 'b')
def func1(a, *, b=42):
...
func1(value_for_a) # b is optional and will default to 42
Required (no default value defined for param 'b'):
def func2(a, *, b):
...
func2(value_for_a, b=21) # b is set to 21 by the function call
func2(value_for_a) # ERROR: missing 1 required keyword-only argument: 'b'`
This can help in cases where you have many similar arguments next to each other especially if they are of the same type, in that case I prefer using named arguments or I create a custom class if arguments belong together.
I'm surprised no one has mentioned the fact that you can mix positional and keyword arguments to do sneaky things like this using *args and **kwargs (from this site):
def test_var_kwargs(farg, **kwargs):
print "formal arg:", farg
for key in kwargs:
print "another keyword arg: %s: %s" % (key, kwargs[key])
This allows you to use arbitrary keyword arguments that may have keys you don't want to define upfront.
I was looking for an example that had default kwargs using type annotation:
def test_var_kwarg(a: str, b: str='B', c: str='', **kwargs) -> str:
return ' '.join([a, b, c, str(kwargs)])
example:
>>> print(test_var_kwarg('A', c='okay'))
A B okay {}
>>> d = {'f': 'F', 'g': 'G'}
>>> print(test_var_kwarg('a', c='c', b='b', **d))
a b c {'f': 'F', 'g': 'G'}
>>> print(test_var_kwarg('a', 'b', 'c'))
a b c {}
Just suplement/add a way for defining the default value of arguments that is not assigned in key words when calling the function:
def func(**keywargs):
if 'my_word' not in keywargs:
word = 'default_msg'
else:
word = keywargs['my_word']
return word
call this by:
print(func())
print(func(my_word='love'))
you'll get:
default_msg
love
read more about *args and **kwargs in python: https://www.digitalocean.com/community/tutorials/how-to-use-args-and-kwargs-in-python-3

Categories

Resources