How to call a function from a list? - python

For example, I have the following list:
method = [fun1, fun2, fun3, fun4]
Then I show a menu where the user must select a number from 1-4 (len(method)). If the user selects i, I have to use the function funi. How can I do that?
Eg.
A=['hello','bye','goodbye']
def hello(n):
print n**2
def bye(n):
print n**3
def goodbye(n):
print n**4
If I want to call the function bye by the array A, using
>>>A[1](7)
Traceback (most recent call last):
File "<pyshell#0>", line 1, in <module>
A[2](5)
TypeError: 'str' object is not callable
How can I use the names saved in A to call my functions? because every method is saved in a string.

Let's see...
You call a function fn by using parens () as in fn()
You access an item from a list by the indexing operator [] as in lst[idx]
So, by combining the two lst[idx](*args)
EDIT
Python list indices are zero-based, so for the first item is 0, the second 1, etc... If the user selects 1-4, you'll have to subtract one.
EDIT
Given the clarification, the following can be done
def method1():
pass
def method2():
pass
methods = [method1, method2]
And you can use the logic above. This way you won't have to mess with actual resolving the string of a name of the function to the actual function.
Keep in mind that functions in python are first class so you can store a reference of them to a list (what we do in methods=[] line)

In your list are not functions but strings (which have "randomly" the same name as the functions). Just put the functions inside the list:
def hello():
pass
mylist = [hello]
mylist[0]()
If you need the name of a function you can use a.__name__ e.g.
def hello():
pass
mylist = [hello]
print("Available functions:")
for function in mylist:
print(function.__name__)

Related

Is there a way to find out what function was called within a list comprehension in another function?

Lets say I'm given a file test.py with the following contents:
def helper():
pass
def test():
foo = [helper() for _ in range(5)]
return foo
Now in another file I want to import test. And then I want to find out what functions were called in test.test. Specifically, I want to be able to know that the function helper was called (just the function name as a string is sufficient).
Is there any way to go about doing that? (no string parsing please, as you can get around it by having a comment for example)
so basically when helper() is executed it returns a string in this case 'helper', so now when you execute the function in the list comprehension it returns that string (in this case 5 times) so if u printed test() and it returned foo u would get a list of 'helper' however if u just returned first item in foo like this foo[0] it would return 'helper'
def helper():
return 'helper'
def test():
foo = [helper() for _ in range(5)]
return foo[0]
print(test())

How do I use a function inside another function and make operations with it in Python?

I'm wondering, how could I use a function that I've already defined inside another function? For example, I have a function f(n). Then I want to create a function g(n) such that it returns f(n)*2.
I'm trying to learn Python and I already know how to use some basic functions, then I tried to make a program to calculate the Greatest Common Divisor of two numbers. I created that function. I called it gcd(a,b), and it returns the GCD of a and b. It worked very well!
Then I want to reuse this function to calculate the Least Common Multiple of a and b.
I used the following code:
def lcm(a,b):
u=gcd(a,b)
v=a*b/u
print(v)
Using the fact that lcm(a,b)*gcd(a,b)=a*b I expect, with this code, that the output to be the LCM of a and b. But when I run the code and use the defined function I get this:
Traceback (most recent call last):
File "<pyshell#0>", line 1, in <module>
lcm(2,2)
File "C:/Users/(my user name)/AppData/Local/Programs/Python/Python37/euclides.py", line 55, in lcm
v=a*b/u
TypeError: unsupported operand type(s) for /: 'int' and 'NoneType'
What does it means and how to solve it?
Change it to return the result rather than just print it:
def lcm(a,b):
u=gcd(a,b)
v=a*b/u
return v
Without the return, it will print the result, then implicitly return None.
You need to make the same change to your gcd function in order for the call to work as intended (it looks like your gcd function is returning None). Also note that in Python 3, gcd is available as math.gcd.
As the TypeError suggests, the error comes from the v=a*b/u line where u is supposed to be the return value from gcd().
It seems that the function gcd() is not returning any value. You need to add return from the gcd() function which you haven't included. As a pseudo code, do something like
def gcd(a, b):
# var = Do some stuff
return var
def lcm(a,b):
u=gcd(a,b)
v=a*b/u
return v
a = # some value
b = # some value
print (lcm(a, b))
You can use different structure also:
class GCD_model:
def gcd(a, b):
# var = Do some stuff
return var
def lcm(a,b, model):
u=model.gcd(a,b)
v=a*b/u
return v
a = # some value
b = # some value
model = GCD_model()
print (lcm(a, b, model))

Python: item.method() and function(item)

What is the logic for picking some methods to be prefixed with the items they are used with, but some are functions that need items as the arguments?
For example:
L=[1,4,3]
print len(L) #function(item)
L.sort() #item.method()
I thought maybe the functions that modify the item need to be prefixed while the ones that return information about the item use it as an argument, but I'm not too sure.
Edit:
What I'm trying to ask is why does python not have L.len()? What is the difference between the nature of the two kinds of functions? Or was it randomly chosen that some operations will be methods while some will be functions?
One of the principles behind Python is There is Only One Way to Do It. In particular, to get the length of a sequence (array / tuple / xrange...), you always use len, regardless of the sequence type.
However, sorting is not supporting on all of those sequence types. This makes it more suitable to being a method.
a = [0,1,2]
b = (0,1,2)
c = xrange(3)
d = "abc"
print len(a), len(b), len(c), len(d) # Ok
a.sort() # Ok
b.sort() # AttributeError: 'tuple' object has no attribute 'sort'
c.sort() # AttributeError: 'xrange' object has no attribute 'sort'
d.sort() # AttributeError: 'str' object has no attribute 'sort'
Something that may help you understand a bit better: http://www.tutorialspoint.com/python/python_classes_objects.htm
What you describe as item.function() is actually a method, which is defined by the class that said item belongs to. You need to form a comprehensive understanding of function, class, object, method and maybe more in Python.
Just conceptually speaking, when you call L.sort(), the sort() method of type/class list actually accepts an argument usually by convention called self that represents the object/instance of the type/class list, in this case L. And sort just like a standalone sorted function but just applies the sorting logic to L itself. Comparatively, sorted function would require an iterable (a list, for example), to be its required argument in order to function.
Code example:
my_list = [2, 1, 3]
# .sort() is a list method that applies the sorting logic to a
# specific instance of list, in this case, my_list
my_list.sort()
# sorted is a built-in function that's more generic which can be
# used on any iterable of Python, including list type
sorted(my_list)
There's a bigger difference between methods and functions than just their syntax.
def foo():
print "function!"
class ExampleClass(object):
def foo(self):
print "method!"
In this example, i defined a function foo and a class ExampleClass with 1 method, foo.
Let's try to use them:
>>> foo()
function!
>>> e = ExampleClass()
>>> e.foo()
method!
>>> l = [3,4,5]
>>> l.foo()
Traceback (most recent call last):
File "<pyshell#7>", line 1, in <module>
l.foo()
AttributeError: 'list' object has no attribute 'foo'
>>>
Even though both have the same name, Python knows that if you do foo(), your calling a function, so it'll check if there's any function defined with that name.
And if you do a.foo(), it knows you're calling a method, so it'll check if there's a method foo defined for objects of the type a has, and if there is, it will call it. In the last example, we try that with a list and it gives us an error because lists don't have a foo method defined.

function accidentally called when defining list

I'm new to Python and I've been working on a project that involves attributes of objects in a list --one of which is a function-- to be called at a later time. However, when I define the list the function is called without it being wanted.
For example in:
x=0
def activateitem():
if x==1:
print('item has been activated')
else:
print('function called')
item=['itemname','red',1,2,activateitem()]
x=1
The result is 'function called'. Is there a way to circumvent this without making the list a function as well? Thanks in advance!
You invoked the function and thus the result was added to the list.
If that is not what you want, you can add the function itself to the list [without invoking it with the parentheses] and then invoke it later by accessing the function within the list [by its index in the list] and then invoking it.
>>> def foo():
... print('hi')
...
>>> l = [1,2,foo]
>>> l
[1, 2, <function foo at 0x7fed39328bf8>]
>>> l[2]()
hi
Add the function to the list without calling it:
item=['itemname','red',1,2,activateitem]
Using the parenthesis calls the function.

why is this giving me an error, python noughts and crosses game

I am getting an error with the first function that I have
def print():
list = [[" ","1","2","3"],["1","-","-","-"],["2","-","-","-"],["3","-","-","-"]]
for item in list:
print(" ".join(item))
def gorow():
userrow = input("row")
return int(userrow)
def gocolumn():
usercolumn = input("column")
return int(usercolumn)
print()
x = list[gorow()][gocolumn()]
print()
Do not use type names as variables names. Change your variable list so it does not conflict with a typename.
And since you named your function print, Python will attempt to recursively call your print function, instead of the actual Python print function. I'm assuming it is then throwing a TypeError because your print function does not take any arguments.
You used a function is already exist. Dont use def print(). Print is already exist. Change the name
Rename function print to myprint
def print():
to
def myprint():
then call it
myprint()

Categories