I see two issues with your solution – one in the way you call your function, one in the implementation of your function:
First, as already pointed out in @sbottingota's answer, you are calling your function with a list, but your function signature and internal logic has been designed as if it should be called with individual values:
- If you have a list
x = [-6, 0, 2]
and call pwfun(x)
, then your args
looks as follows: ([1, 2, 3],)
; in other words, you will have your list of values wrapped inside a one-element tuple. As a consequence, when iterating over the values in args
in your loop, you will get the list [-6, 0, 2]
as the first and only value for your loop variable x
, which ends in a comparison of a list ([-6, 0, 2]
) with an integer (-1
), which is undefined.
- If you call
pwfun(*x)
instead, with the same list x
, this will be the same as calling pwfun(-6, 0, 2)
, i.e. the same as calling your function with the individual elements of the list. Then *args
will gather them into a new list (or rather, tuple), which will look as expected: (-6, 0, 2)
. As a consequence, when iterating over args
you will iterate over the individual values, as expected.
However (second issue), in your for-loop, you will return in each if-statement. This means that the loop will never reach any element after the first element in args
, as you will have already exited both your loop and your function with returning the result for your first element only.
There are two solutions that I can think of for your problem: (1) gathering the results in a list again, (2) using a generator function. Let's have a look at the individual solutions in the following sections.
Your solution
def pwfun(*args):
for x in args:
if x < -1:
return(-2 * (x + 1))
elif x > 1:
return(x**2 - 1)
else:
return(0)
x = [-6, 0, 2]
result = pwfun(*x)
print(f"Calling pwfun(*x) with x = {x}:")
print(f"The result is of type {type(result)} and looks as follows: {result}")
# >>> Calling pwfun(*x) with x = [-6, 0, 2]:
# >>> The result is of type <class 'int'> and looks as follows: 10
As you can see, the function only returns a result for the first value in args
.
Side note: In python, return
is a keyword, not a function or anything that is called; so while writing return(0)
etc. works, you would normally write return 0
without the brackets.
Solution with result list
def pwfun_list(*args):
result = []
for x in args:
if x < -1:
result.append(-2 * (x + 1))
elif x > 1:
result.append(x ** 2 - 1)
else:
result.append(0)
return result
x = [-6, 0, 2]
result = pwfun_list(*x)
print(f"Calling pwfun_list(*x) with x = {x}:")
print(f"The result is of type {type(result)} and looks as follows: {result}.")
print("The individual values are:")
for value in result:
print(value)
# >>> Calling pwfun_list(*x) with x = [-6, 0, 2]:
# >>> The result is of type <class 'list'> and looks as follows: [10, 0, 3].
# >>> The individual values are:
# >>> 10
# >>> 0
# >>> 3
Here, we iterate over the values in args
, but rather than returning results immediately, we append them to a new list result
, which we return once, at the very end. As a result, we have evaluated the function for all values rather than only for the first one.
Solution with generator
def pwfun_gen(*args):
for x in args:
if x < -1:
yield -2 * (x + 1)
elif x > 1:
yield x ** 2 - 1
else:
yield 0
x = [-6, 0, 2]
result = pwfun_gen(*x)
print(f"Calling pwfun_gen(*x) with x = {x}:")
print(f"The result is of type {type(result)} and looks as follows: {result}.")
print("The individual values are:")
for value in result:
print(value)
# >>> Calling pwfun_gen(*x) with x = [-6, 0, 2]:
# >>> The result is of type <class 'generator'> and looks as follows: <generator object pwfun_gen at 0x000001E8AE3787B0>.
# >>> The individual values are:
# >>> 10
# >>> 0
# >>> 3
This solution looks more similar to your original solution. However, as we replaced return
with yield
, we will get a generator in return when calling pwfun_gen(*x)
.
The generator will then provide the result for each individual element in args
(and not only for the first one), once we iterate over it with for value in result
. In contrast to a list, however, this last step will work only once, and then the generator will be "exhausted".
The concept of generators is maybe a bit less intuitive than a regular Python function (at least that's what I think). You can find a good introduction here, if you are interested.