So i have a function which takes multiple values:
def kgV(a,b, *rest):
#the function itself doesnt matter for the question
#beside that it returns an int no matter how many arguments where passed
now i have a list or range():
# for example
myRange = range(2, 10)
myList = [2,9,15]
Now i want it to possible to give my Function the list or range as parameter so that it works as if i had given the every int of the range or list as parameter.
#how can i make this work?
kgV(myRange)
kgV(myList)
i tried some things like: for i in a etc
but they all returned errors :-/
edit: i just solved it using a help function but it seems a very un pythonic way of doing it, so is there a more pythonic / generic way of doing it?
def kgVList(liste):
result = liste[0]
for i in liste:
result = kgV(i, result)
return result
You can simply unpack the values like this:
kgV(*a)
Related
I'm new to python and my professor gave us the assignment to write different functions. Writing the function is easy but he gave us examples of what the output should be and it kind of threw me off.
>>> average([])
0.0
>>> average([1.0])
1.0
>>> average([5.0, 10.0, 20.0])
11.666666666666666
This was the example. How can I place square brackets around my input like that?
def average(inputlist)
return sum(inputlist)/len(inputlist)
If you do this
average([2, 4, 5])
The function will know you are passing a list parameter since python is a dynamically typed language, that is - the type of the parameter inputlist will be determined at runtime.
Alternatively, you could just define your list first, then pass it to the function like this.
inputValues = [2, 4, 5]
average(inputValues)
Create a list and then append your inputs to the list and then apply the function
Try this code:
nums = []
n = int(input())
for i in range(n):
nums.append(int(input()))
average(nums)
This above code will take an input n and then it takes n input numbers and then applies the average (any mathematical function).
Square parenthesis in python signify that your function is taking in an list as one of it's arguments.
You would take multiple inputs and append them to a list, which later you would input in the function.
Therefore your code will look like this:
def average(listOfNumbers):
total = sum(listOfNumbers)
return float(total)/len(listOfNumbers)
numOfInputs = int(input("Number of inputs: "))
numbers = []
for i in range(numOfInputs):
numbers.append(int(input("Enter Number: ")))
print(average(numbers))
def average(*args):
for i in args:
return sum(i)/len(i)
print(average([42,67,23,89]))
That means that your function has to take a list as an input. Therefore, you should assume your function is like below:
def average(input):
# input looks like [0,5,6]
I hope this helps.
My first script doesn't return the result of the whole input list, and the second one doesnt return iterable tuple. Any advice?
input= [0.1, 0.2]
def newvalue():
for i in input:
value=integrate.quad(lambda i:(np.exp(-i))/i,i,np.inf)
return value[0]
print(newvalue()) #1.8229239584193715
If I use the following script it does the work and it prints all the values which results from the input list, but the problem with this script that I can't iterate through the calculated values.
for i in input:
value = integrate.quad(lambda i: (np.exp(-i)) / i, i, np.inf)
print(value[0]) #1.8229239584193715
#1.2226505441838773
As said in the comments, you need to create a loop and append the values inside just like so:
import numpy as np
from scipy import integrate
input_= [0.1, 0.2]
def newvalue():
values = []
for i in input_:
value=integrate.quad(lambda i:(np.exp(-i))/i,i,np.inf)
values.append(value[0])
return values
print(newvalue()) #[1.8229239584193715, 1.2226505441838773]
The first script only provides one value because you have a return in the loop — the loop doesn’t continue after that.
There are two typical ways to handle this situation. The first is to create an empty array before your loop, add each result to the array during the loop, and return that results array after the loop. That approach is ok if the number of values / loops is small, i.e. you don’t want to build up a 10,000,000 element array.
If the number of values / loops is bigger, or if your outer function may not need all the values, use a yield in place of your return. That allows the called function to generate each value as needed when called from an outer loop.
After calling return statements the function does not continue and all information is lost that has not been either returned or is not referenced by a variable outside the function scope.
The answer from Anwarvic should do the trick.
Your function should not take it's argument from a global variable.
You can define your function so that it accepts one value, and returns the caluclated result for this value.
def newvalue(input):
value=integrate.quad(lambda i:(np.exp(-i))/i,i,np.inf)
return value
You can then query it in a few different fashions :
In a loop
for i in [0.1, 0.2]:
print(newvalue(i))
Or via list comprehension :
inputs = [0.1,0.2]
answers = [newvalue(i) for i in inputs]
print(answers)
In your first example simply replace the command
return value[0]
with
yield value[0]
Then you may use a newvalue() in these forms, for example:
list(newvalue()) to obtain a list of all calculated values,
for i in newvalue(): to iterate through calculated values.
The question asks to build a program that calculates the square root for input numbers, i figured out how to do the operation, but the output i got has a different format from the one given in the task.
The output of the program should be:
18,22,24
However, mine is like this: [18,22,24]
This is an example answer given:
from math import *
C,H = 50,30
def calc(D):
D = int(D)
return str(int(sqrt((2*C*D)/H)))
D = input().split(',')
D = list(map(calc,D))
print(",".join(D))
I thought .join() is a string method, and it seems that D here is a list, and the join method works.
This is my answer:
import math
c=50
h=30
list_d = input('enter').split(',')
list_q = []
for d in list_d:
d = float(d)
q = round(math.sqrt((2*c*d)/h))
list_q.append(q)
print(''.join(list_q))
Somehow, i can't use join method on my list_q and i got an error says:
print(''.join(list_q))
TypeError: sequence item 0: expected str instance, int found
It's confusing...
Thanks to whoever could explain a little bit!
The issue is not with the string you're calling join on, or with the list itself, but with the values inside the list. str.join expects its argument to be a list of strings, but you're passing it a list of integers. It won't convert them for you!
Fortunately, you can fix the pretty easily. Rather than appending q to your list, append str(q). You can see str being called in the example function too!
Trying to iterate over range of numbers (or list) to check if values are equal. Seems very simple, but I cant seem to find a way to do it.
I am trying to use an if statement to check scope of items in a 2D array.
# check if x is equal to var if added to any number between 0 and 10.
if var == x + any(range(10)): # not how it works, but how I want it to
# do something
After looking into any() I realize that It just returns True if any item in the iterate is True
Use any this way, also use generator:
if any(var==(x+i) for i in range(10)):
# do something
You have to use several Python functions for that:
if var in list(map(lambda item: x+item, range(10)))
list: Casts the parameter into a list object.
map: Applies a function (first parameter) to a collection of values (second parameter).
lambda: Lambda function.
You can also use this non-any version:
for i in range(10):
if var == (x+i):
break
Another way to do it using numpy:
import numpy as np
if var in x + np.arange(10) :
# do something
Would suffer from floating point problem if your numbers are not integers.
when I'm calling SCIPY functions, I surely don't want to have to look up the documentation [kidding] but slightly more serious is that I don't want to have to accept all the return values. For example, I am calling FMIN_BFGS(). It has the option to return a bunch of values, I only want to keep the returned minimum. So I type
res = fmin_bfgs(...)
Dies with "too many values to unpack". I thought I had read that this would work
res, = fmin_bfgs(...)
but it gives the same error message. Finally what worked is to use answer of question #431866
res, _, _ , _ = fmin_bfgs(...)
But really? Do I have to check the documentation and count number of return values and use that many underscores or is there some more Pythonesque way to ignore everything returned except the first value.
Thanks, J.
Actually, your first example will work:
res = fmin_bfgs(...)
Then you can reference the values you're interested in with res[0].
In python 3 only, you could also do:
res, *_ = fmin_bgfs(...)
Which assigns the first value from the tuple to res, and the remaining values as a new tuple to _.
Functions like this return a tuple of values. The return statement looks something like
return arr1, scalar2, label3
When this happens you have several options:
mytuple = foo(...) # accept the tuple
print(len(mytuple)) # look at the number of items
val1= mytuple[0] # select the 1st item
Or you can use the tuple unpack option
a, b, c = mytuple
a, b, c = foo(...)
a, _, _ = foo(...) # _ is just a name for unimportant value
you can using the indexing right away
a = foo(...)[0]
The
a, = foo(...)
a, = (12,) # works
a, = (12,12,12) # unpacking error
only works when foo returns a single item tuple. It's most useful as a way of enforcing the 'rule' that this function returns that tuple count. The left hand side , functions just like the right hand side one - designating a tuple.
So this is a basic Python issue - how to unpack or select items from a tuple. It's not special to Scipy.
================
But a quick glance at fmin_bfgs indicates that I can get either one item (not tuple unpacking), 7 items if I ask for full output, or 8 if I ask for a further value.
Dumb error on my part. What my code actually looked like was
res, l2e = fmin_bfgs(...)
except I had not defined res to be an array, like I should have done. So the interpreter thought I was giving a size=2 vector to populate the size=N answer back from fmin_bfgs. Once I define res=np.zeros(N) before the call then everything works fine.
Sorry to have wasted your time...