import math
def square(*args):
return math.pow(args,2)
a=[]
for i in range(1,101):
a.append(i)
print(list(map(square,a)))
Is there something wrong about this code? I am getting this error:
TypeError: must be real number, not tuple
As #heemayl mentioned in the comments, args is a tuple. Therefore, to access a single element of the tuple you need to use an indexer:
def square(*args):
return math.pow(args[0], 2)
Alternatively, if you are only providing one argument you can pass it straight through with the need to unpack a tuple:
def square(x):
return math.pow(x, 2)
Related
According to this, I can call a function that takes N arguments with a tuple containing those arguments, with f(*my_tuple).
Is there a way to combine unpacking and unpacked variables?
Something like:
def f(x,y,z):...
a = (1,2)
f(*a, 3)
The code you supplied (f(*a, 3)) is valid for python 3. For python 2, you can create a new tuple by adding in the extra values. Then unpack the new tuple.
For example if you had the following function f:
def f(x, y, z):
return x*y - y*z
print(f(1,2,3))
#-4
Attempting your code results in an error in python 2:
a = (1,2)
print(f(*a,3))
#SyntaxError: only named arguments may follow *expression
So just make a new tuple:
new_a = a + (3,)
print(f(*new_a))
#-4
Update
I should also add another option is to pass in a named argument after the * expression (as stated in the SyntaxError):
print(f(*a, z=3))
#-4
A little heavy, but you can use functools.partial to partially apply f to the arguments in a before calling the resulting callable on 3.
from functools import partial
partial(f, *a)(3)
This is more useful if you plan on making a lot of calls to f with the same two arguments from a, but with different 3rd arguments; for example:
a = (1,2)
g = partial(f, *a)
for k in some_list:
g(k) # Same as f(1,2,k)
as #pault said - you can create a new tuple , and you can do another thing which is:
pass the *a as the last variable to a function, for example :
def f(x,y,z):...
a = (1,2)
f(3, *a)
worked for me in Python 2.7
I realise that in the below functions f returns a tuple, and g returns a list.
def f():
return 1,2
def g():
return [1,2]
a,b=f()
c,d=g()
I have written a function which can handle any number of arguments.
def fun(*args):
return args
These arguments are entered like the f function above because they are the return value from a previous function.
output = fun(other_func())
When more that one value is return from fun the individual values can be retrieved by stating something like this...
output1, output2 = fun(other_func())
However, when one argument is used the output is something like below...
output = fun(other_func())
(1,)
Is there a way when there is only one value to have it return a single element instead of a tuple but still have the functionality of being able to return more than one value?
If you know the function is always going to return a one-element tuple, you can use a one-element tuple assignment:
output, = fun(other_func())
or simply index:
output = fun(other_func())[0]
But in this case, a simple Don't do that, don't return a tuple might also apply:
output = other_func()
As long as *args is a tuple, returning args will therefore return a tuple, even if there is only one parameter.
You should probably do something like:
def fun(*args):
if len(args) == 1:
args, = args
return args
This might be what you are looking for. With this method you must have at least one argument, but you will catch the other arguments in other if you have more.
def funct(*args):
return args
# end funct
if __name__ == '__main__':
foo, *other = funct(1, 2, 3, 4)
print(foo)
First of all, I'm super new to python and I actually search for my problem but the examples were to heavy to understand.
Here is my homework; I need a function which takes two functions as an argument and returns if the results of the two functions are same or not? Basically, it will give either TRUE of FALSE.
For that I wrote:
def f(x,y,z):
k=x(*z)
l=y(*z)
return k == l
The previos code I wrote for single function was working but when I modified it for two function as above, it gives an error as following :
import math
>>> f(math.sqrt,math.cos,5)
Traceback (most recent call last):
File "<pyshell#56>", line 1, in <module>
f(math.sqrt,math.cos,5)
File "D:/Users/karabulut-ug/Desktop/yalanmakinesi.py", line 2, in f
k=x(*z)
TypeError: sqrt() argument after * must be a sequence
>>>
I could not figured it out since the error giving function is normally does not take a sequence. So I dont think it makes a sense :) Any help is appreciated.. Thanks :)
z is just a single number, but the * argument expansion syntax requires that you pass in a sequence (like a list, tuple or str, for example).
Either remove the * (and make your function work for just single arguments), or use *z in the function signature to make z a tuple of 0 or more captured arguments:
def f(x, y, z):
k = x(z)
l = y(z)
return k == l
or
def f(x, y, *z):
k = x(*z)
l = y(*z)
return k == l
The latter now works for functions with more than one argument too:
f(math.pow, math.log, 10, 10)
If you added a **kw argument to the signature, then keyword arguments could be handled too:
def f(x, y, *args, **kwargs):
k = x(*args, **kwargs)
l = y(*args, **kwargs)
return k == l
Here I renamed z to args to better reflect its purpose.
The syntax *z invokes argument unpacking on z. When z is just an integer, there is no iterator behavior defined, and so you see this error. Try:
>>> f(math.sqrt, math.cos, [5])
You need to remove the *. Its for unpacking. So:
def f(x,y,z):
k=x(z)
l=y(z)
return k == l
You use the * operator when you want to pass in an iterable object, like a list or tuple as something thats split up. So, for example:
a = [1,2,3,4,5]
So, for an arbitrary function, f:
f(*a) = f(1,2,3,4,5)
I'd like to learn how to pass an arbitrary number of args in a python function, so I wrote a simple sum function in a recursive way as follows:
def mySum(*args):
if len(args) == 1:
return args[0]
else:
return args[-1] + mySum(args[:-1])
but when I tested mySum(3, 4), I got this error:
TypeError: unsupported operand type(s) for +: 'int' and 'tuple'
Does anyone have an idea about this and gimme some clue to correct it?
This line:
return args[-1] + mySum(args[:-1])
args[:-1] returns a slice of the arguments tuple. I assume your goal is to recursively call your function using that slice of the arguments. Unfortunately, your current code simply calls your function using a single object - the slice itself.
What you want to do instead is to call with those args unrolled.
return args[-1] + mySum(*args[:-1])
^---- note the asterisk
This technique is called "unpacking argument lists," and the asterisk is sometimes (informally) called the "splat" operator.
If you don't want to do it recursively:
def mySum(*args):
sum = 0
for i in args:
sum = sum + i
return sum
args[:-1] is a tuple, so the nested call is actually mySum((4,)), and the nested return of args[0] returns a tuple. So you end up with the last line being reduced to return 3 + (4,). To fix this you need to expand the tuple when calling mySum by changing the last line to return args[-1] + mySum(*args[:-1]).
In your code, args[:-1] is a tuple, so mySum(args[:-1]) is being called with the args being a tuple containing another tuple as the first argument. You want to call the function mySum with args[:-1] expanded to the arguments however, which you can do with
mySum(*args[:-1])
The arbitrary arguments are passed as tuple (with one asterisk*) to the function, (you can change it to a list as shown in the code) and calculate the sum of its elements, by coding yourself using a for loop; if don't want to use the sum() method of python.
def summing(*arg):
li = list(*arg)
x = 0
for i in range((len(li)-1)):
x = li[i]+x
return x
#creating a list and pass it as arbitrary argument to the function
#to colculate the sum of it's elements
li = [4, 5 ,3, 24, 6, 67, 1]
print summing(li)
Option1:
def mySum(*args):
return sum(args)
mySum(1,2,3) # 6
mySum(1,2) # 3
Option 2:
mySum2 = lambda *args: sum(args)
mySum2(1,2,3) # 6
mySum2(1,2) # 3
I have a class where each instance is basically of a bunch of nested lists, each
of which holds a number of integers or another list containing integers, or a
list of lists, etc., like so:
class Foo(list):
def __init__(self):
self.extend(
list(1), list(2), list(3), range(5), [range(3), range(2)]
)
I want to define a method to walk the nested lists and give me
one integer at a time, not unlike os.walk. I tried this:
def _walk(self):
def kids(node):
for x in node:
try:
for y in kids(x):
yield y
except TypeError:
yield x
return kids(x)
But it immediately raises a stopiteration error. If I add a print statement to print each "node" in the first for loop, the function appears to iterate over the whole container in the way I want, but without yielding each node. It just prints them all the first time I call next on the generator.
I'm stumped. Please help!
It works if you change return kids(x) to return kids(self)
Here's a function that is a simpler version of your _walk method that does what you want on an arbitrary iterable. The internal kids function is not required.
def walk(xs):
for x in xs:
try:
for y in walk(x):
yield y
except TypeError:
yield x
This could be trivially adapted to work as a method on your Foo object.