Combining functions in python - python

I need to run a function as following:
def func1(a):
l=a+1
print (l)
def func2(a,b):
l=a+1
z.append(l)
l=b+1
z.append(l)
print (l)
def func2(a,b,c):
l=a+1
z.append(l)
l=b+1
z.append(l)
l=c+1
z.append(l)
print (l)
and so on. Can somebody show me an alternative where I can combine all these functions to one function where I can add as many values as I want (a,b,c,d..) and the output given will be a+1,b+1,c+1,d+1... in a list?

You can define a function to take a variable number of parameters, and then use a list comprehension to work on them in one statement like:
Code:
def increment_to_list(*args):
return [a + 1 for a in args]
Test Code:
print(increment_to_list(1,2,3))
print(increment_to_list(4,5,6,7,8))
Results:
[2, 3, 4]
[5, 6, 7, 8, 9]

I think you want to do something like this:
def f(*args):
l = []
for i in args:
l.append(i+1)
return l
Or, if you like list comprehensions like me, you could do:
def f(*args):
return [val + 1 for val in args]

I think you want variable number of arguments with list output:
def myFunc(*args):
return [i+1 for i in args]
Now you can get your z from this function like this:
z = myFunc(1,2,3,4)
z
#[2, 3, 4, 5]

Related

pass multiple arguments to a function

I wish to define a function that takes in 3 arguments,
each of which is a variable-length list as follows:
a = [1,2,3]
b = [4,5,6]
c = [7,8,9]
def functionName(*args1,*args2,*args3):
res1 = [i for i in args1]
res2 = [i for i in args2]
res3 = [i for i in args3]
return res1,res2,res3
Now i wish to call functionName as follows:
functionName(a,b,c)
and get the three lists back.
However, I get hit with the following error:
File "<ipython-input-178-8d50368fdacf>", line 15
def functionName(*args1,*args2,*args3):
^
SyntaxError: invalid syntax
How can I implement a function whose arguments contain variable-length lists/arrays?
Why not just declare the function as follows:
def functionName(list1, list2, list3):
res1 = [i for i in list1]
res2 = [i for i in list2]
res3 = [i for i in list3]
return res1, res2, res3
I think that should work as you want it to.
When you pass in *args into a function that allows you to pass in more than the formally defined number of positional arguments, i.e. if you had something like
def func(a,b,*args):
print(a,b)
for arg in args:
print(arg)
And then you called the function as
a = 10
b = 20
func(a, b, 35, 40)
your output would be
(10, 20)
35
40
You can also do something much simpler like this.
a = [1,2,3]
b = [4,5,6]
c = [7,8,9]
def functionName(*args1):
for i in range(len(args1)):
print (args1[i])
functionName(a,b,c)
This will result in:
[1, 2, 3]
[4, 5, 6]
[7, 8, 9]
Without the for loop, you can just give
print (args1)
It will give you the lists inside a tuple.
([1, 2, 3], [4, 5, 6], [7, 8, 9])
If you change it to:
functionName(a,c)
It will result in:
([1, 2, 3], [7, 8, 9])
Remember, *args1 will take in all the arguments you are sending and store them as a tuple.
See more details on *args and **kwargs here:
https://www.geeksforgeeks.org/args-kwargs-python/
https://realpython.com/python-kwargs-and-args/
As far as my understanding goes there you are passing 3 list objects to a function, so there is no need to type "*" before function parameter. List can be of variable size.
function(*args) is used when the number of parameters passed to the function are variable and unknown.
Ex:
def function(*args):
print(len(args))
>>> function(1,2,3,4)
4
>>> function(1,2)
2

How can I create a list out of the arguments given in a function?

I am a beginner in Python3 and I am trying to figure out how I can solve this exercise:
Define a function called myfunc that takes in an arbitrary number of arguments ans returns a list containing only those arguments that are even.
I tried this:
def myfunc(*args):
a= list(args)
for num in a:
if num%2==0:
return num
When trying to call out myfunc(1,2,3,4,5,6) it takes only the first even number:2.Why does this happen?
How can I create a list that returns only the even numbers?
The problem is you are returning after finding the first value, so it will only return the first value. You could try something like this:
def myfunc(*args):
return [num for num in args if num % 2 == 0]
print(myfunc(1, 2, 3, 4, 5, 6))
Output
[2, 4, 6]
The above method uses a list comprehension. An equivalent solution, albeit less pythonic, is the following:
def myfunc(*args):
result = []
for num in args:
if num % 2 == 0:
result.append(num)
return result
args is just an regular iterable. So
return [value for value in args if value%2==0]
At your current code, you don't get the whole list because you call return when you find the first value.
The issue is once your function executes return thats it, so what you want to do is append all those values to a list and return that entire list
def myfunc(*args):
a= list(args)
b = []
for num in a:
if num%2==0:
b.append(num)
return b
b = myfunc(1, 2, 3, 4, 5, 6)
print(b)
(xenial)vash#localhost:~/python/stack_overflow$ python3.7 helping.py
[2, 4, 6]
Looking forward, just to show you you can cut some bulk out of here, note that 2 % 2 = 0 right so we can say if not 2% since not 0 will evaluate to True and meet our conditions that way
def myfunc(*args):
lista = []
for i in list(args):
if not i % 2:
lista.append(i)
return lista
lista = myfunc(1, 2, 3, 4, 5, 6)
print(lista)
And once you really fall in love <3
def myfunc(*args):
return [i for i in list(args) if not i % 2]
def myfunc(*args):
list = [num for num in args if num%2==0]
return(list)

Python : how to make 1-D array from 2-D array

I have array2D = [[1,2,3],[4,5,6]]. What I want is a function which takes an index and returns the elements in 1D array.
Example: fn(0) -> returns [1,4]
fn{1) -> returns [2,5]
I need a fast way to do this.
you can use lambda and list comprehension:
array2D = [[1,2,3],[4,5,6]]
fn = lambda x: [item[x] for item in array2D]
print(fn(0)) # [1, 4]
print(fn(1)) # [2, 5]
print(fn(2)) # [3, 6]
as suggested in the comments, you may apply the same concept with a function definition:
def fn(x): return [item[x] for item in array2D]
print(fn(0)) # [1, 4]
print(fn(1)) # [2, 5]
print(fn(2)) # [3, 6]
Lambda functions are pretty useful, and let you define operation in a really clear way.
In our example, our lambda accept a variable x, which represent the index we want of each item in array2D
Then you have list comprehension, similarly to lambda function, they are a really powerful tool and a must in python
In this situation you should prefear the function definiton, as suggested by PEP-8.
The following list comprehension will work:
def fn(i, lst):
return [sublst[i] for sublst in lst]
>>> array2D = [[1, 2, 3], [4, 5, 6]]
>>> fn(0, array2D)
[1, 4]
>>> fn(1, array2D)
[2, 5]
You can use operator.itemgetter:
array2D = [[1,2,3],[4,5,6]]
from operator import itemgetter
def fn(x, k):
return list(map(itemgetter(k), x))
fn(array2D, 0) # [1, 4]
If you want to define new functions for retrieving a specific index, you can do so via functools.partial:
from functools import partial
def fn(x, k):
return list(map(itemgetter(k), x))
get_zero_index = partial(fn, k=0)
get_zero_index(array2D) # [1, 4]
Here are my two cents using slicing (I have to use additional np.array() for this because your original data was a list):
array2D = np.array([[1,2,3],[4,5,6]])
def fn(n): return (list(array2D[:,n]))
print (fn(0), fn(1), fn(2))
How about a generator?
We could use zip to pack them, then create a empty list to store the generated data:
class myZip(object):
__slots__ = ('zipData', 'interList')
def __init__(self, *args):
self.zipData = zip(*args)
self.interList = []
def __call__(self, index):
try:
return self.interList[index]
except IndexError:
try:
if index == 0:
self.interList.append(next(self.zipData))
return self.interList[index]
for i in range(index-(len(self.interList)-1)):
self.interList.append(next(self.zipData))
return self.interList[index]
except StopIteration:
raise IndexError("index out of range")
def __iter__(self):
for i in self.interList:
yield i
for i in self.zipData:
yield i
array2D = [[1,2,3],[4,5,6]]
a = myZip(*array2D)
print(a(2))
print(a(1))
print(a(0))
---
(3, 6)
(2, 5)
(1, 4)
The benefits of this is we do not need to produce all data at once.

How to pass one argument from list and another argument in the built-in function map() in Python?

In Python, one could apply a function foo() to every element of a list by using the built-in function map() as follows:
def foo(x):
return x*x
print map(foo, [1, 2, 3, 4])
This would print as one could guess: 1 4 9 16.
Lets say the function foo() now accepts two arguments instead of one, and is defined as follows:
def foo(x, y):
return x+y
In this case, x is an element of the list, and y is some number which is the same for the whole list. How can we use map() in this case such that foo() is applied on every element of the list, while taking another argument y which is the same for every element?
I would like to be able to do something like:
print map(foo(:, 5), [1, 2, 3, 4])
which should give me: 6 7 8 9.
Is it possible in Python? There could be alternatives for this particular example of adding 'y' to all the elements. But I am looking for an answer that would use map().
You can use a lambda function. This is treated just like a normal function, with the x value being the parameter for your iterator, and the return value being x+5 in this case.
>>> def foo(x, y)
... return x + y
...
>>> l = [1, 2, 3, 4]
>>> map(lambda x: foo(x, 5), l)
[6, 7, 8, 9]
For the record, #PaoloMoretti had this in before me :)
One way to do this is with functools.partial:
>>> from functools import partial
>>> def foo(x, y):
... return x + y
...
>>> l = [1, 2, 3, 4]
>>> map(partial(foo, y=2), l)
[3, 4, 5, 6]
>>>
Another way is to change the way you define the function:
>>> def foo(y):
... def inner(x):
... return x + y
... return inner
...
>>> map(foo(2), l)
[3, 4, 5, 6]
>>>
Incidentally, using lambda would be the most straightforward way to do this, as Paolo Moretti said. Any particular reason why you have to use map() the way you described?

Passing a list while retaining the original

So I'm teaching myself Python, and I'm having an issue with lists. I want to pass my function a list and pop items off it while retaining the original list. How do I make python "instance" the passed list rather that passing a pointer to the original one?
Example:
def burninate(b):
c = []
for i in range(3):
c.append(b.pop())
return c
a = range(6)
d = burninate(a)
print a, d
Output: [0, 1, 2] [5, 4, 3]
Desired output: [0, 1, 2, 3, 4, 5] [5, 4, 3]
Thanks!
As other answers have suggested, you can provide your function with a copy of the list.
As an alternative, your function could take a copy of the argument:
def burninate(b):
c = []
b = list(b)
for i in range(3):
c.append(b.pop())
return c
Basically, you need to be clear in your mind (and in your documentation) whether your function will change its arguments. In my opinion, functions that return computed values should not change their arguments, and functions that change their arguments should not return anything. See python's [].sort(), [].extend(), {}.update(), etc. for examples. Obviously there are exceptions (like .pop()).
Also, depending on your particular case, you could rewrite the function to avoid using pop() or other functions that modify the argument. e.g.
def burninante(b):
return b[:-4:-1] # return the last three elements in reverse order
You can call burninate() with a copy of the list like this:
d = burninate(a[:])
or,
d = burninate(list(a))
The other alternative is to make a copy of the list in your method:
def burninate(b):
c=[]
b=b[:]
for i in range(3):
c.append(b.pop())
return c
>>> a = range(6)
>>> b = burninate(a)
>>> print a, b
>>> [0, 1, 2, 3, 4, 5] [5, 4, 3]
A slightly more readable way to do the same thing is:
d = burninate(list(a))
Here, the list() constructor creates a new list based on a.
A more general solution would be to import copy, and use copy.copy() on the parameter.
Other versions:
def burninate(b):
c = []
for i in range(1, 4):
c.append(b[-i])
return c
def burninate(b):
c = b[-4:-1]
c.reverse()
return c
And someday you will love list comprehensions:
def burninate(b):
return [b[-i] for i in range(1,4)]
You can use copy.deepcopy()
burninate = lambda x: x[:-4:-1]

Categories