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
Related
This is a question out of curiosity rather than trying to use it for a practical purpose.
Consider I have the following simple example where I generate a list through list comprehension:
>>> a = [1, 2, 3]
>>> b = [2 * i for i in a]
>>> b
[2, 4, 6]
>>> b.append(a)
>>> b
[2, 4, 6, [1, 2, 3]]
However if I try and do this all in one action
>>> a = [1, 2, 3]
>>> b = [2 * i for i in a].append(a)
>>> b == None
True
The result returns None. Is there any reason why this is the case?
I would have thought that an action like this would either return an answer like in the first example or throw an error.
For reference I'm using Python 3.6.5
append only works on variables, not list literals, since it updates the list object itself and does not return the resulting list.
As #Tomalak mentioned noted, running a similar operation on a simple list also returns None
>>> [1, 2, 3].append(4) == None
True
You can use concatination + instead of append in list comprehension
In [1]: a = [1, 2, 3]
In [2]: b = [2 * i for i in a] + [a]
In [3]: b
Out[3]: [2, 4, 6, [1, 2, 3]]
#ScottMcC, methods defined on mutable objects like list, dictionary mostly perform operations on calling object and doesn't return anything.
In case of immutable object like string you may see, methods return the modified form(a different object) of the calling object. In case of list, it's different.
You can't expect the below operations on list kind of mutable objects.
s = "hello DJANGO"
s2 = s.upper()
s3 = s.lower()
print(s) # hello DJANGO
print(s2) # HELLO DJANGO
print(s3) # hello django
Now, have a look at the below examples.
list is mutable object.
Calling sort() method on list directly modified the calling object and doesn't return anything (That's why None).
Calling sorted() function doesn't alter the passing list. It creates a separate sorted list based on the passed list. As it is not a method defined on list object, it returns the new sorted list.
append() method appends item on the calling list and doesn't return anything. Once you call it, you are done with updating (appending an item) the list.
# sort() method defined on list updates the calling list
# As it updates current list, it doesn't return anything. That's why None.
a = [5, 8, 1, 2, 7]
n = a.sort()
print (a)
print(n)
print ()
# sorted() function returns a new sorted list
# It doesn't update the calling list a2
a2 = [5, 8, 1, 2, 7];
n = sorted(a2);
print (a2)
print(n)
print()
# append() is method defined on list, it updates calling list so it doesn't return anything (None)
l = []
n = l.append(34)
print(l)
print (n)
Output
[1, 2, 5, 7, 8]
None
[5, 8, 1, 2, 7]
[1, 2, 5, 7, 8]
[34]
None
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]
I am wanting to append two returned lists to two different lists such as
def func():
return [1, 2, 3], [4, 5, 6]
list1.append(), list2.append() = func()
Any ideas?
You'll have to capture the return values first, then append:
res1, res2 = func()
list1.append(res1)
list2.append(res2)
You appear to be returning lists here, are you certain you don't mean to use list.extend() instead?
If you were extending list1 and list2, you could use slice assignments:
list1[len(list1):], list2[len(list2):] = func()
but this is a) surprising to newcomers and b) rather unreadable in my opinion. I'd still use the separate assignment, then extend calls:
res1, res2 = func()
list1.extend(res1)
list2.extend(res2)
Why not just storing the return values?
a, b = func() #Here we store it in a and b
list1.append(a) #append the first result to a
list2.append(b) #append the second one to b
With this, if a was previously [10] and b was previously [20], you'll have this result:
>>> a, b
[10, [1,2,3]], [20,[4,5,6]]
Nah, that wasn't difficult, was it?
By the way, you probably want to merge the lists. For this, you can use extend:
list1.extend(a)
Hope it helps!
A one line solution isn't possible (unless you use some cryptic hack, which is always a bad idea).
The best you can get is:
>>> list1 = []
>>> list2 = []
>>> def func():
... return [1, 2, 3], [4, 5, 6]
...
>>> a,b = func() # Get the return values
>>> list1.append(a) # Append the first
>>> list2.append(b) # Append the second
>>> list1
[[1, 2, 3]]
>>> list2
[[4, 5, 6]]
>>>
It's readable and efficient.
I have an array that matches the parameters of a function:
TmpfieldNames = []
TmpfieldNames.append(Trademark.name)
TmpfieldNames.append(Trademark.id)
return func(Trademark.name, Trademark.id)
func(Trademark.name.Trademark.id) works, but func(TmpfieldNames) doesn't. How can I call the function without explicitly indexing into the array like func(TmpfieldNames[0], TmpfieldNames[1])?
With * you can unpack arguments from a list or tuple and ** unpacks arguments from a dict.
>>> range(3, 6) # normal call with separate arguments
[3, 4, 5]
>>> args = [3, 6]
>>> range(*args) # call with arguments unpacked from a list
[3, 4, 5]
Example from the documentation.
I think what you are looking for is this:
def f(a, b):
print a, b
arr = [1, 2]
f(*arr)
What you are looking for is:
func(*TmpfieldNames)
But this isn't the typical use case for such a feature; I'm assuming you've created it for demonstration.
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]